/**
 @file sys_usw_flow_stats.c

 @date 2009-12-22

 @version v2.0

*/

/****************************************************************************
 *
* Header Files
*
****************************************************************************/
#include "ctc_error.h"
#include "ctc_macro.h"
#include "ctc_stats.h"
#include "ctc_hash.h"
#include "sys_usw_common.h"
#include "sys_usw_stats.h"
#include "sys_usw_ftm.h"
#include "sys_usw_chip.h"
#include "sys_usw_opf.h"
#include "sys_usw_port.h"
#include "sys_usw_qos_api.h"
#include "sys_usw_l3if.h"
#include "sys_usw_nexthop_api.h"
#include "sys_usw_dma.h"
#include "sys_usw_interrupt.h"
#include "sys_usw_register.h"
#include "sys_usw_acl_api.h"
#include "sys_usw_wb_common.h"
#include "sys_usw_dmps.h"
#include "sys_usw_register.h"

#include "drv_api.h"
#include "usw/include/drv_common.h"

/****************************************************************************
 *
* global variable
*
*****************************************************************************/
sys_stats_master_t* usw_flow_stats_master[CTC_MAX_LOCAL_CHIP_NUM_PP] =
{
    NULL
};

/****************************************************************************
 *
* Defines and Macros
*
*****************************************************************************/
#define SYS_STATS_INIT_CHECK() \
    do { \
        LCHIP_CHECK(lchip); \
        if (usw_flow_stats_master[lchip] == NULL){ \
            SYS_STATS_DBG_OUT(CTC_DEBUG_LEVEL_INFO, " Feature not initialized \n");\
            return CTC_E_NOT_INIT;\
        } \
    } while (0)

#define SYS_STATS_TYPE_CHECK(type) \
    do { \
        if ((type < CTC_STATS_TYPE_FWD) || (type >= CTC_STATS_TYPE_MAX)) \
            return CTC_E_NOT_SUPPORT; \
    } while (0)

#define SYS_STATS_TYPE_ENABLE(type) (usw_flow_stats_master[lchip]->stats_bitmap & type)

#define STATS_LOCK(lchip)   \
    do { \
        if (usw_flow_stats_master[lchip]->p_stats_mutex) sal_mutex_lock(usw_flow_stats_master[lchip]->p_stats_mutex); \
    } while (0)

#define STATS_UNLOCK(lchip) \
    do { \
        if (usw_flow_stats_master[lchip]->p_stats_mutex) sal_mutex_unlock(usw_flow_stats_master[lchip]->p_stats_mutex); \
    } while (0)

#define CTC_ERROR_RETURN_UNLOCK(op) \
    do { \
        int32 rv; \
        if ((rv = (op)) < 0) \
        { \
            sal_mutex_unlock(usw_flow_stats_master[lchip]->p_stats_mutex); \
            return (rv); \
        } \
    } while (0)

#define SYS_STATS_USE_TOTAL_CNT(lchip, ram_type)   (\
    ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && ((ram_type == SYS_STATS_RAM_QUE) || (ram_type <= SYS_STATS_RAM_IPE_ACL15))) ||\
    (DRV_FROM_AT(lchip) && (((ram_type >= SYS_STATS_RAM_AT_QUE_UC)&& (ram_type <= SYS_STATS_RAM_AT_PORTTC_MC)) || (ram_type <= SYS_STATS_RAM_AT_IPE_ACL23)))\
)
#define SYS_STATS_ENCODE_SYS_PTR(type, offset)  (((type) << 16) | ((offset)&0xFFFF))
#define SYS_STATS_ENCODE_CHIP_32K_PTR(type, offset)  ((SYS_STATS_RAM_SDC == (type)) ? ((1 << 15) | ((offset) & 0x7FFF)) : \
                                                                                        ((((((type) >= SYS_STATS_RAM_IPE_PRIVATE0) && ((type) <= SYS_STATS_RAM_IPE_PRIVATE3)) || (type)== SYS_STATS_RAM_EPE_PRIVATE0) << 16) \
                                                                                            | (((SYS_STATS_RAM_QUEUE == (type)) ? 0 : ((type) <= SYS_STATS_RAM_EPE_PRIVATE0 ? (type)%4 : ((type)-1)%4)) << 12) \
                                                                                            | ((offset) & 0x1FFF)))
#define SYS_STATS_IS_STABLE_EN(stats_ptr) CTC_IS_BIT_SET(stats_ptr, 23)
#define SYS_STATS_SET_STABLE_EN(stats_ptr, set) ((set) ? CTC_BIT_SET(stats_ptr, 23) : CTC_BIT_UNSET(stats_ptr, 23))
#define SYS_STATS_DECODE_PTR_RAM(ptr)          (((ptr)>>16)&0x7F)
#define SYS_STATS_DECODE_PTR_OFFSET(ptr)        ((ptr)&0xFFFF)
#define SYS_STATS_PTR_MASK(ptr)      ((ptr)&0x7FFFFF)

#define SYS_STATS_IPE_ACL_NUM    16  /*TMM*/
#define SYS_STATS_EPE_ACL_NUM    4   /*TMM*/
#define SYS_STATS_GLB_NUM        8   /*TMM*/
#define SYS_ACL_RAM_NUM          32

#define SYS_STATS_DEFAULT_PKT_CNT_THREASHOLD      0x8FFF
#define SYS_STATS_DEFAULT_BYTE_CNT_THREASHOLD     0x8FFF
#define SYS_STATS_DEFAULT_FIFO_INTERRUPT_THREASHOLD     0x3F

#define STATS_SHARE_ACL_PTR(ptr) ((sys_stats_statsid_acl_t*)ptr)
#define STATS_SHARE_ACL_FLD(ptr, field) ((SYS_STATS_TYPE_ACL == (ptr)->stats_id_type)? STATS_SHARE_ACL_PTR((ptr))->field: 0)
#define STATS_SHARE_NPM_PTR(ptr) ((sys_stats_statsid_npm_im_t*)ptr)
#define STATS_SHARE_NPM_FLD(ptr, field) ((SYS_STATS_TYPE_NPM_IM == (ptr)->stats_id_type) ? STATS_SHARE_NPM_PTR((ptr))->field: 0)


/* for AT, map lchip by stats type pp_en*/
#define SYS_MAP_LCHIP_WITH_LOCK(lchip, pp_base, type, dir)\
{\
    uint8 pp_en = 0;\
    pp_en = usw_flow_stats_master[(pp_base)]->stats_type[(dir)][(type)].pp_en;\
    if (!pp_en && (lchip) != (pp_base))\
    {\
        (lchip) = (pp_base);\
    }\
    STATS_LOCK(lchip);\
}

#define SYS_TMM_STATS_TYPE_VRF(lchip, ctc_stats_type)   (DRV_FROM_TMM(lchip) && CTC_STATS_STATSID_TYPE_VRF == ctc_stats_type)
#define SYS_TMM_STATS_TYPE_SDC(lchip, ctc_stats_type)   (DRV_FROM_TMM(lchip) && CTC_STATS_STATSID_TYPE_SDC == ctc_stats_type)
#define SYS_AT_STATS_TYPE_NPM_IM(lchip, ctc_stats_type)   (DRV_FROM_AT(lchip) && CTC_STATS_STATSID_TYPE_NPM_IM == ctc_stats_type)
#define SYS_AT_NSH_STATS_NUM    (2047)
#define SYS_STATS_SYNC_FIFO_ENTRY_NUM 32
#define SYS_STATS_SYNC_FIFO(lchip)\
{\
    if (MCHIP_F_STATS(lchip)->sync_fifo_stats)\
    {\
        MCHIP_F_STATS(lchip)->sync_fifo_stats(lchip);\
    }\
}

extern int32
ctc_hash_get_count(ctc_hash_t* hash, uint32* count);
extern int32
sys_usw_mac_stats_dump_db(uint8 lchip, sal_file_t p_f,ctc_global_dump_db_t* p_dump_param);
extern int32
sys_usw_flow_stats_dump_db(uint8 lchip, sal_file_t p_f,ctc_global_dump_db_t* p_dump_param);
extern int32
drv_usw_ftm_get_flow_stats_table_id(uint8 lchip, uint8 ram_idx, uint32* table_id);
extern int32
_sys_usw_flow_stats_ram_alloc(uint8 lchip);

#define __1_STATS_COMMON__

uint8
_sys_usw_flow_stats_encode_hw_ram(uint8 lchip, uint8 ram, uint8 dir)
{
    uint8 hw_st_ram = 0;
    if(DRV_FROM_AT(lchip))
    {
        if(ram <= SYS_STATS_RAM_AT_EPE_ACL11)
        {
            hw_st_ram = ram ;
        }
        else if(ram <= SYS_STATS_RAM_AT_IPE_ACL23)
        {
            hw_st_ram = ram - SYS_STATS_RAM_AT_IPE_ACL0;
        }
        else
        {
            if(dir == CTC_INGRESS)
            {
                hw_st_ram = ram - SYS_STATS_RAM_AT_GLOBAL0 + 24;
            }
            else
            {
                hw_st_ram = ram - SYS_STATS_RAM_AT_GLOBAL8 + 12;
            }
        }
    }
    else
    {
        if (ram <= SYS_STATS_RAM_EPE_ACL3)
        {
            hw_st_ram = ram - SYS_STATS_RAM_EPE_ACL0;
        }
        else if (ram <= SYS_STATS_RAM_IPE_ACL15)
        {
            hw_st_ram = ram - SYS_STATS_RAM_IPE_ACL0;
        }
        else
        {
            if (dir == CTC_INGRESS)
            {
                hw_st_ram = ram - SYS_STATS_RAM_GLOBAL0 + 16;
            }
            else
            {
                hw_st_ram = ram - SYS_STATS_RAM_GLOBAL0 + 4;
            }
        }
    }
    return hw_st_ram;
}

uint32
_sys_usw_flow_stats_encode_hw_ptr(uint8 lchip, uint8 ram, uint32 offset)
{
    uint32 hw_stats_ptr = 0;
    uint32 is_acl = 0;
    uint32 ram_bits = 0;

    if(DRV_FROM_AT(lchip))
    {
        if(SYS_STATS_RAM_AT_QUE_MC== ram|| SYS_STATS_RAM_AT_QUE_UC== ram)
        {
            hw_stats_ptr = offset;
        }
        else
        {
            if(ram >= SYS_STATS_RAM_AT_GLOBAL0 && ram <= SYS_STATS_RAM_AT_GLOBAL7)
            {
                ram_bits = ram - SYS_STATS_RAM_AT_GLOBAL0;
            }
            else if (ram >= SYS_STATS_RAM_AT_GLOBAL8 && ram <= SYS_STATS_RAM_AT_GLOBAL15)
            {
                ram_bits = ram - SYS_STATS_RAM_AT_GLOBAL8;
            }
            hw_stats_ptr = (ram_bits << MCHIP_CAP(SYS_CAP_STATS_HW_LOCAL_STATSPTR_BIT_NUM)) | (offset & 0x1FFF);
        }
    }
    else if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        if(SYS_STATS_RAM_QUE == ram)
        {
            hw_stats_ptr = offset;
        }
        else
        {
            if(ram >= SYS_STATS_RAM_GLOBAL0 && ram <= SYS_STATS_RAM_GLOBAL7)
            {
                ram_bits = ram - SYS_STATS_RAM_GLOBAL0;
            }
            hw_stats_ptr = (ram_bits << MCHIP_CAP(SYS_CAP_STATS_HW_LOCAL_STATSPTR_BIT_NUM)) | (offset & 0x1FFF);
        }
    }
    else
    {
        if(ram == SYS_STATS_RAM_SDC)
        {
            if(DRV_IS_DUET2(lchip))
            {
                hw_stats_ptr = (1 << 14) | (offset & 0x3FFF);
            }
            else
            {
                hw_stats_ptr = (1 << 15) | (offset & 0x7FFF);
            }
        }
        else
        {
            is_acl = ((ram >= SYS_STATS_RAM_IPE_PRIVATE0) && (ram <= SYS_STATS_RAM_IPE_PRIVATE3)) || ram == SYS_STATS_RAM_EPE_PRIVATE0;
            if(SYS_STATS_RAM_QUEUE == ram)
            {
                ram_bits = 0;
            }
            else
            {
                if(ram == SYS_STATS_RAM_EPE_PRIVATE0)
                {
                    ram_bits = 0;
                }
                else
                {
                    ram_bits = (ram-1)%4;
                }
            }
            if(DRV_IS_DUET2(lchip))
            {
                hw_stats_ptr = (is_acl << 15) | (ram_bits << MCHIP_CAP(SYS_CAP_STATS_HW_LOCAL_STATSPTR_BIT_NUM)) | (offset & 0xFFF);
            }
            else
            {
                hw_stats_ptr = (is_acl << 16) | (ram_bits << MCHIP_CAP(SYS_CAP_STATS_HW_LOCAL_STATSPTR_BIT_NUM)) | (offset & 0x1FFF);
            }
        }
    }

    return hw_stats_ptr;
}

/*not suit for acl & sdc */
uint8
_sys_usw_flow_stats_decode_hw_ptr(uint8 lchip, uint8 type, uint8 dir, uint32 hw_stats_ptr)
{
    uint8 ram = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);
    uint32 ram_bits = 0;

    if(DRV_FROM_AT(lchip))
    {
        if(type == SYS_STATS_TYPE_QUEUE)
        {
            ram = SYS_STATS_RAM_AT_QUE_UC;
        }
        else if(type == SYS_STATS_TYPE_QUEUE_MC)
        {
            ram = SYS_STATS_RAM_AT_QUE_MC;
        }
        else if(type == SYS_STATS_TYPE_ACL)
        {
            ram_bits = hw_stats_ptr >> MCHIP_CAP(SYS_CAP_STATS_HW_LOCAL_STATSPTR_BIT_NUM);
            if(dir == CTC_INGRESS)
            {
                if(ram_bits > MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM))
                {
                    ram = ram_bits -MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM) + SYS_STATS_RAM_AT_GLOBAL0;
                }
                else
                {
                    ram = ram_bits +SYS_STATS_RAM_AT_IPE_ACL0;
                }
            }
            else
            {
                if(ram_bits > MCHIP_CAP(SYS_CAP_ACL_EGRESS_LKUP_NUM))
                {
                    ram = ram_bits -MCHIP_CAP(SYS_CAP_ACL_EGRESS_LKUP_NUM) + SYS_STATS_RAM_AT_GLOBAL8;
                }
                else
                {
                    ram = ram_bits +SYS_STATS_RAM_AT_EPE_ACL0;
                }
            }
        }
        else
        {
            ram_bits = hw_stats_ptr >> MCHIP_CAP(SYS_CAP_STATS_HW_LOCAL_STATSPTR_BIT_NUM);
            if(dir == CTC_INGRESS)
            {
                ram = SYS_STATS_RAM_AT_GLOBAL0 + ram_bits;
            }
            else
            {
                ram = SYS_STATS_RAM_AT_GLOBAL8 + ram_bits;
            }
        }
    }
    else if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        if(type == SYS_STATS_TYPE_QUEUE)
        {
            ram = SYS_STATS_RAM_QUE;
        }
        else if (type == SYS_STATS_TYPE_ACL)
        {
            ram_bits = hw_stats_ptr >> MCHIP_CAP(SYS_CAP_STATS_HW_LOCAL_STATSPTR_BIT_NUM);
            if(dir == CTC_INGRESS)
            {
                if(ram_bits > MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM))
                {
                    ram = ram_bits -MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM) + SYS_STATS_RAM_GLOBAL0;
                }
                else
                {
                    ram = ram_bits +SYS_STATS_RAM_IPE_ACL0;
                }
            }
            else
            {
                if(ram_bits > MCHIP_CAP(SYS_CAP_ACL_EGRESS_LKUP_NUM))
                {
                    ram = ram_bits -MCHIP_CAP(SYS_CAP_ACL_EGRESS_LKUP_NUM) + SYS_STATS_RAM_GLOBAL0;
                }
                else
                {
                    ram = ram_bits +SYS_STATS_RAM_EPE_ACL0;
                }
            }
        }
        else
        {
            ram_bits = hw_stats_ptr >> MCHIP_CAP(SYS_CAP_STATS_HW_LOCAL_STATSPTR_BIT_NUM);
            ram = SYS_STATS_RAM_GLOBAL0 + ram_bits;
        }
    }
    else
    {
        if(type == SYS_STATS_TYPE_QUEUE)
        {
            ram = SYS_STATS_RAM_QUEUE;
        }
        else if(type == SYS_STATS_TYPE_SDC)
        {
            ram = SYS_STATS_RAM_SDC;
        }
        else
        {
            if(DRV_IS_DUET2(lchip))
            {
                ram_bits = hw_stats_ptr >> MCHIP_CAP(SYS_CAP_STATS_HW_LOCAL_STATSPTR_BIT_NUM);
            }
            else
            {
                ram_bits = hw_stats_ptr >> MCHIP_CAP(SYS_CAP_STATS_HW_LOCAL_STATSPTR_BIT_NUM);
            }
            if(dir == CTC_INGRESS)
            {
                ram = SYS_STATS_RAM_IPE_GLOBAL0 + ram_bits;
            }
            else
            {
                ram = SYS_STATS_RAM_EPE_GLOBAL0 + ram_bits;
            }
        }
    }

    return ram;
}

STATIC uint32
_sys_usw_flow_stats_vec_cnt(uint8 lchip)
{
    uint8 ram = 0;
    uint8 stats_ram_num = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);
    uint32 total_cnt = 0;

    for (ram=0; ram<stats_ram_num; ram++)
    {
        total_cnt += usw_flow_stats_master[lchip]->flow_stats_vec[ram]->used_cnt;
    }
    return total_cnt;
}

STATIC int32
_sys_usw_flow_stats_map_type(uint8 lchip, ctc_stats_statsid_type_t ctc_type, uint8 is_vc, uint8* p_sys_type, uint8* p_dir)
{
    uint8 type = 0;
    CTC_PTR_VALID_CHECK(p_sys_type);

    switch(ctc_type)
    {
    case CTC_STATS_STATSID_TYPE_VLAN:
        type = SYS_STATS_TYPE_VLAN;
        *p_dir = CTC_BOTH_DIRECTION;
        break;

    case CTC_STATS_STATSID_TYPE_VRF:
        type = SYS_STATS_TYPE_VRF;
        *p_dir = CTC_INGRESS;
        break;

    case CTC_STATS_STATSID_TYPE_ACL:
    case CTC_STATS_STATSID_TYPE_ACL2:
        type = SYS_STATS_TYPE_ACL;
        *p_dir = CTC_BOTH_DIRECTION;
        break;

    case CTC_STATS_STATSID_TYPE_IP/*CTC_STATS_STATSID_TYPE_IPMC*/:
        type = SYS_STATS_TYPE_FIB;
        *p_dir = CTC_INGRESS;
        break;

    case CTC_STATS_STATSID_TYPE_MAC:
        type = SYS_STATS_TYPE_MAC;
        *p_dir = CTC_INGRESS;
        break;

    case CTC_STATS_STATSID_TYPE_FLOW_HASH:
        type = SYS_STATS_TYPE_FLOW_HASH;
        *p_dir = CTC_INGRESS;
        break;

    case CTC_STATS_STATSID_TYPE_MPLS:
        type = is_vc ? SYS_STATS_TYPE_PW : SYS_STATS_TYPE_LSP;
        *p_dir = CTC_INGRESS;
        break;

    case CTC_STATS_STATSID_TYPE_MPLS_PW:
        type = SYS_STATS_TYPE_PW;
        *p_dir = CTC_INGRESS;
        break;

    case CTC_STATS_STATSID_TYPE_TUNNEL:
        type = SYS_STATS_TYPE_TUNNEL;
        *p_dir = CTC_BOTH_DIRECTION;
        break;

    case CTC_STATS_STATSID_TYPE_SCL:
        type = SYS_STATS_TYPE_SCL;
        *p_dir = CTC_BOTH_DIRECTION;
        break;

    case CTC_STATS_STATSID_TYPE_NSH:
        type = SYS_STATS_TYPE_NSH;
        *p_dir = CTC_EGRESS;
        break;

    case CTC_STATS_STATSID_TYPE_NEXTHOP:
        type = SYS_STATS_TYPE_FWD_NH;
        *p_dir = CTC_EGRESS;
        break;

    case CTC_STATS_STATSID_TYPE_NEXTHOP_MPLS_PW:
        type = SYS_STATS_TYPE_PW;
        *p_dir = CTC_EGRESS;
        break;

    case CTC_STATS_STATSID_TYPE_NEXTHOP_MPLS_LSP:
        type = SYS_STATS_TYPE_LSP;
        *p_dir = CTC_EGRESS;
        break;

    case CTC_STATS_STATSID_TYPE_L3IF:
        type = SYS_STATS_TYPE_INTF;
        *p_dir = CTC_BOTH_DIRECTION;
        break;

    case CTC_STATS_STATSID_TYPE_FID:
        type = DRV_FROM_AT(lchip) ? SYS_STATS_TYPE_FID : SYS_STATS_TYPE_VLAN;
        *p_dir = CTC_BOTH_DIRECTION;
        break;

    case CTC_STATS_STATSID_TYPE_NEXTHOP_MCAST:
        type = SYS_STATS_TYPE_FWD_NH;
        *p_dir = CTC_INGRESS;
        break;

    case CTC_STATS_STATSID_TYPE_ECMP:
        type = SYS_STATS_TYPE_ECMP;
        *p_dir = CTC_INGRESS;
        break;
   case CTC_STATS_STATSID_TYPE_HECMP:
        type = DRV_FROM_AT(lchip)? SYS_STATS_TYPE_HECMP : SYS_STATS_TYPE_ECMP;
        *p_dir = CTC_INGRESS;
        break;

    case CTC_STATS_STATSID_TYPE_SDC:
        type = SYS_STATS_TYPE_SDC;
        *p_dir = CTC_INGRESS;
        break;
    case CTC_STATS_STATSID_TYPE_PORT:
        type = SYS_STATS_TYPE_PORT;
        *p_dir = CTC_BOTH_DIRECTION;
        break;
    case CTC_STATS_STATSID_TYPE_POLICER0:
        type = SYS_STATS_TYPE_POLICER0;
        *p_dir = CTC_BOTH_DIRECTION;
        break;
    case CTC_STATS_STATSID_TYPE_POLICER1:
        type = SYS_STATS_TYPE_POLICER1;
        *p_dir = CTC_BOTH_DIRECTION;
        break;
    case CTC_STATS_STATSID_TYPE_NPM_IM:
        type = SYS_STATS_TYPE_NPM_IM;
        *p_dir = CTC_BOTH_DIRECTION;
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }

    *p_sys_type = type;

    return CTC_E_NONE;
}
/*
STATIC int32
_sys_stats_flow_stats_map_dma_blkid(uint8 lchip, uint32 stats_ptr, uint8* p_blkid)
{
    uint8 ram = 0;
    uint32 offset = 0;
    uint8 blkid = 0;
    sys_stats_ram_prop_t* p_ram = NULL;

    ram = SYS_STATS_DECODE_PTR_RAM(stats_ptr);
    offset = SYS_STATS_DECODE_PTR_OFFSET(stats_ptr);
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[ram]);

    blkid = (p_ram->base_idx + offset)/MCHIP_CAP(SYS_CAP_STATS_DMA_BLOCK_SIZE);
    *p_blkid = blkid;

    return CTC_E_NONE;
}
*/
int32
sys_usw_flow_stats_get_ram_info(uint8 lchip, uint8 blkid, uint32* offset, uint32* total)
{

    if (blkid < MCHIP_CAP(SYS_CAP_STATS_RAM_NUM))
    {
        *offset = usw_flow_stats_master[lchip]->p_stats_ram[blkid].base_idx;
        *total = usw_flow_stats_master[lchip]->p_stats_ram[blkid].total_cnt;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_map_ramid(uint8 lchip, uint16 num, sys_stats_param_t* p_statsid, uint8* p_ramid)
{
    sys_stats_ram_prop_t* p_ram = NULL;
    uint8 i = 0;
    uint32 field_val = 0;
    uint32 cmd = 0;
    uint32 lkup_level_bitmap = 0;
    uint8 ram_num = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);
    uint16 avl_cnt = 0;

    CTC_PTR_VALID_CHECK(p_ramid);
    CTC_MIN_VALUE_CHECK(num, 1);
    if (!DRV_FROM_AT(lchip))
    {
        cmd = DRV_IOR(IpeFlowHashCtl_t, IpeFlowHashCtl_igrIpfix32KMode_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
    }
    if (p_statsid->flag & SYS_STATS_FLAG_ACL_STABLE)
    {
        CTC_BIT_SET(lkup_level_bitmap, p_statsid->acl_pri);
    }
    else if ((SYS_STATS_TYPE_ACL == p_statsid->type))
    {
        lkup_level_bitmap = sys_usw_acl_get_lkup_level_bmp(lchip, p_statsid->dir, p_statsid->acl_pri);
    }

    for (i = 0; i < ram_num; i++)
    {
        p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[i]);
        avl_cnt = SYS_STATS_USE_TOTAL_CNT(lchip, i)? p_ram->total_cnt : p_ram->total_cnt - 1;
        if (CTC_IS_BIT_SET(p_ram->stats_bmp[p_statsid->dir], p_statsid->type) && (p_ram->used_cnt + num <= avl_cnt))
        {
            if(field_val && p_statsid->type == SYS_STATS_TYPE_FLOW_HASH)
            {
                *p_ramid = i;
                break;
            }
            if ((SYS_STATS_TYPE_ACL == p_statsid->type) && !CTC_IS_BIT_SET(lkup_level_bitmap, p_ram->acl_priority))
            {
                continue;
            }
            if ((SYS_STATS_TYPE_SCL == p_statsid->type) && p_ram->scl_bmp && !CTC_IS_BIT_SET(p_ram->scl_bmp, p_statsid->acl_pri))
            {
                continue;
            }
            *p_ramid = i;
            return CTC_E_NONE;
        }
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_read_count(uint8 lchip, uint16 stats_idx, uint8 ram, ctc_stats_basic_t* p_count)
{
    uint32 cmd = 0;
    ds_t   ds;
    uint32 tbl_id = 0;
    uint32 entry_num = 0;
    ctc_stats_basic_t temp_count;
    uint8 instance = 0;
    uint8 dp_id = 0;
#if (1 == SDK_WORK_PLATFORM)
    drv_work_platform_type_t platform_type = 0;
#endif

    if (DRV_FROM_TMM(lchip))
    {
        drv_usw_ftm_get_flow_stats_table_id(lchip, ram, &tbl_id);
    }
    else
    {
        tbl_id=DsStats_t;
    }
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    if (DRV_FROM_AT(lchip) && (MEM_TYPE_PEER_DP == TABLE_ENTRY_TYPE(lchip, tbl_id)
        || MEM_TYPE_PER_DP == TABLE_ENTRY_TYPE(lchip, tbl_id)))
    {
        entry_num = (MEM_TYPE_PEER_DP == TABLE_ENTRY_TYPE(lchip, tbl_id)) ? DRV_TABLE_MAX_INDEX(lchip, tbl_id)>>1 : DRV_TABLE_MAX_INDEX(lchip, tbl_id);
        if (SYS_VCHIP_DUAL_CORE_MODE(lchip))
        {
            instance = (stats_idx/entry_num) & 1;
            dp_id = (stats_idx/entry_num) >> 1;
        }
        else
        {
            dp_id = (stats_idx/entry_num);
        }
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, DRV_INS(instance, stats_idx%entry_num), DRV_CMD_DP_EN(cmd, dp_id), &ds));
    }
    else
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, stats_idx, DRV_CMD_PP_EN(cmd), &ds));
    }
    SYS_STATS_DBG_INFO( "tbl_id:%d, stats_idx:%d\n",tbl_id, stats_idx);
    CTC_ERROR_RETURN(MCHIP_F_STATS(lchip)->ds2count(lchip, tbl_id, &ds, &temp_count));
    p_count->byte_count += temp_count.byte_count;
    p_count->packet_count += temp_count.packet_count;
#if (1 == SDK_WORK_PLATFORM)
    CTC_ERROR_RETURN(drv_get_platform_type(lchip, &platform_type));
    if ((SW_SIM_PLATFORM == platform_type) && usw_flow_stats_master[lchip]->clear_read_en)
    {
        sal_memset(ds, 0, sizeof(ds_t));
        cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
        if (DRV_FROM_AT(lchip) && (MEM_TYPE_PEER_DP == TABLE_ENTRY_TYPE(lchip, tbl_id)
        || MEM_TYPE_PER_DP == TABLE_ENTRY_TYPE(lchip, tbl_id)))
        {
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, DRV_INS(instance, stats_idx%entry_num), DRV_CMD_DP_EN(cmd, dp_id), &ds));
        }
        else
        {
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, stats_idx, DRV_CMD_PP_EN(cmd), &ds));
        }
        SYS_STATS_DBG_INFO( "clear stats:0x%04X by software in uml\n", stats_idx);
    }
#endif
    return CTC_E_NONE;
}

#define __2_STATS_DB__

STATIC int32
_sys_usw_flow_stats_entry_create(uint8 lchip, uint16 num, uint32 stats_id, uint32 stats_ptr)
{
    uint16 i = 0;
    uint16 proc_num = num;
    sys_stats_flow_stats_t* p_flow_stats = NULL;
    uint8 ram = 0;
    uint16 ptr_offset= 0;

    CTC_MIN_VALUE_CHECK(num, 1);

    ram = SYS_STATS_DECODE_PTR_RAM(stats_ptr);

    for (i=0; i<proc_num; i++)
    {
        ptr_offset = SYS_STATS_DECODE_PTR_OFFSET(stats_ptr + i);
        p_flow_stats = ctc_vector_get(usw_flow_stats_master[lchip]->flow_stats_vec[ram], ptr_offset);
        if (p_flow_stats)
        {
            SYS_STATS_DBG_ERROR(" Entry exists stats_ptr=0x%.8x p_flow_stats=%p \n", (uint32)p_flow_stats->stats_ptr, p_flow_stats);
            continue;
        }

        p_flow_stats = (sys_stats_flow_stats_t*)mem_malloc(MEM_STATS_MODULE, sizeof(sys_stats_flow_stats_t));
        if (NULL == p_flow_stats)
        {
            proc_num = i;
            SYS_STATS_DBG_ERROR(" No memory \n");
            goto error_roll;
        }

        sal_memset(p_flow_stats, 0, sizeof(sys_stats_flow_stats_t));
        p_flow_stats->stats_ptr = stats_ptr+i;
        p_flow_stats->stats_id = stats_id;
        /*p_flow_stats->flag = flag;*/

        /* add it to fwd stats hash */
        if (!ctc_vector_add(usw_flow_stats_master[lchip]->flow_stats_vec[ram], ptr_offset, p_flow_stats))
        {
            SYS_STATS_DBG_ERROR(" Entry insert fail stats_ptr=0x%.8x p_flow_stats=%p \n", p_flow_stats->stats_ptr, p_flow_stats);
            goto error_roll;
        }

        if(DRV_FROM_TMM(lchip))
        {
            CTC_BMP64_SET(usw_flow_stats_master[lchip]->statsptr_bmp[ram].bmp, ptr_offset);
            if (1 == usw_flow_stats_master[lchip]->p_stats_ram[ram].used_cnt && (((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && ram != SYS_STATS_RAM_QUE)||
                (DRV_FROM_AT(lchip) && ram != SYS_STATS_RAM_AT_QUE_UC && ram != SYS_STATS_RAM_AT_QUE_MC )))
            {
                sys_usw_dma_set_cfg_size(lchip, SYS_DMA_FLOW_STATS_CHAN_ID, ram, TRUE);
            }
        }
        else if(ram < SYS_STATS_RAM_SDC)
        {
            CTC_BMP64_SET(usw_flow_stats_master[lchip]->statsptr_bmp[ram].bmp, ptr_offset);
        }
    }

    return CTC_E_NONE;

error_roll:

    for (i=0; i<proc_num; i++)
    {
        ptr_offset = SYS_STATS_DECODE_PTR_OFFSET(stats_ptr + i);
        p_flow_stats = ctc_vector_get(usw_flow_stats_master[lchip]->flow_stats_vec[ram], ptr_offset);
        if (!p_flow_stats)
        {
            continue;
        }

        if(DRV_FROM_TMM(lchip))
        {
            CTC_BMP64_UNSET(usw_flow_stats_master[lchip]->statsptr_bmp[ram].bmp, ptr_offset );
            if (0 == usw_flow_stats_master[lchip]->p_stats_ram[ram].used_cnt && (((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && ram != SYS_STATS_RAM_QUE)||
                (DRV_FROM_AT(lchip) && ram != SYS_STATS_RAM_AT_QUE_UC && ram != SYS_STATS_RAM_AT_QUE_MC )))
            {
                sys_usw_dma_set_cfg_size(lchip, SYS_DMA_FLOW_STATS_CHAN_ID, ram, FALSE);
            }
        }
        else if(ram < SYS_STATS_RAM_SDC)
        {
            CTC_BMP64_UNSET(usw_flow_stats_master[lchip]->statsptr_bmp[ram].bmp, ptr_offset);
        }

        ctc_vector_del(usw_flow_stats_master[lchip]->flow_stats_vec[ram], ptr_offset);
        mem_free(p_flow_stats);
    }

    return CTC_E_NO_MEMORY;
}

STATIC int32
_sys_usw_flow_stats_entry_delete(uint8 lchip, uint16 num, uint32 stats_ptr)
{
    uint16 i = 0;
    uint16 ptr_offset = 0;
    int32 ret = CTC_E_NONE;
    sys_stats_flow_stats_t flow_stats;
    sys_stats_flow_stats_t* p_flow_stats = NULL;
    void* p_ret = NULL;
    uint8 ram = 0;

    CTC_MIN_VALUE_CHECK(num, 1);

    sal_memset(&flow_stats, 0, sizeof(flow_stats));
    ram = SYS_STATS_DECODE_PTR_RAM(stats_ptr);

    for (i=0; i<num; i++)
    {
        ptr_offset = SYS_STATS_DECODE_PTR_OFFSET(stats_ptr + i);
        p_flow_stats = ctc_vector_get(usw_flow_stats_master[lchip]->flow_stats_vec[ram], ptr_offset);
        if (p_flow_stats)
        {
            if(DRV_FROM_TMM(lchip))
            {
                CTC_BMP64_UNSET(usw_flow_stats_master[lchip]->statsptr_bmp[ram].bmp, (flow_stats.stats_ptr & 0xffff));
                if (0 == usw_flow_stats_master[lchip]->p_stats_ram[ram].used_cnt)
                {
                    sys_usw_dma_set_cfg_size(lchip, SYS_DMA_FLOW_STATS_CHAN_ID, ram, FALSE);
                }
            }
            else if(ram < SYS_STATS_RAM_SDC)
            {
                CTC_BMP64_UNSET(usw_flow_stats_master[lchip]->statsptr_bmp[ram].bmp, (flow_stats.stats_ptr & 0xffff));
            }
            p_ret = ctc_vector_del(usw_flow_stats_master[lchip]->flow_stats_vec[ram], ptr_offset);
            if (NULL == p_ret)
            {
                SYS_STATS_DBG_ERROR(" Entry remove fail stats_ptr=0x%.8x p_flow_stats=%p \n", (uint32)p_flow_stats->stats_ptr, p_flow_stats);
            }
            mem_free(p_flow_stats);
        }
        else
        {
            SYS_STATS_DBG_ERROR(" Entry not exist \n");
    		ret = CTC_E_NOT_EXIST;
            continue;
        }
    }

    return ret;
}

STATIC int32
_sys_usw_flow_stats_entry_lookup(uint8 lchip, uint32 stats_ptr, sys_stats_flow_stats_t** pp_fwd_stats)
{
    sys_stats_flow_stats_t* p_flow_stats = NULL;
    uint16 ptr_offset = 0;
    uint8 ram = 0;

    CTC_PTR_VALID_CHECK(pp_fwd_stats);

    *pp_fwd_stats = NULL;
    ram = SYS_STATS_DECODE_PTR_RAM(stats_ptr);
    ptr_offset = SYS_STATS_DECODE_PTR_OFFSET(stats_ptr);
    p_flow_stats = ctc_vector_get(usw_flow_stats_master[lchip]->flow_stats_vec[ram], ptr_offset);
    if (p_flow_stats)
    {
        *pp_fwd_stats = p_flow_stats;
    }
    else
    {
        return CTC_E_ENTRY_NOT_EXIST;
    }

    return CTC_E_NONE;
}

#define __3_STATS_STATSPTR__
STATIC int32
_sys_usw_flow_stats_alloc_statsptr(uint8 lchip, sys_stats_param_t* p_statsid)
{
    uint32 offset = 0;
    sys_usw_opf_t opf;
    sys_stats_prop_t* p_prop = NULL;
    sys_stats_ram_prop_t* p_ram = NULL;
    int32  ret;
    uint16 num = p_statsid->num;

    SYS_STATS_DBG_FUNC();
    CTC_MIN_VALUE_CHECK(num, 1);

    p_prop = &(usw_flow_stats_master[lchip]->stats_type[p_statsid->dir][p_statsid->type]);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type = usw_flow_stats_master[lchip]->opf_type_flow_stats;
    opf.pool_index = 0xFF;
    CTC_ERROR_RETURN(_sys_usw_flow_stats_map_ramid(lchip, num, p_statsid, &opf.pool_index));
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[opf.pool_index]);

    if(DRV_FROM_TMM(lchip))
    {
        if(opf.pool_index == 0xFF)
        {
            return CTC_E_NO_RESOURCE;
        }
    }
    else
    {
        if (opf.pool_index == 0xFF
            || usw_flow_stats_master[lchip]->alloc_count + num > DRV_TABLE_MAX_INDEX(lchip, DsStats_t)
            || (!CTC_IS_BIT_SET(p_ram->stats_bmp[p_statsid->dir], p_statsid->type)))
        {
            SYS_STATS_DBG_ERROR(" No resource in ASIC \n");
            return CTC_E_NO_RESOURCE;
        }
    }
    if (p_statsid->type == SYS_STATS_TYPE_NSH)
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_last(lchip, &opf, num, &offset));
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(lchip, &opf, num, &offset));
    }
    /*Can not use stats ptr 0 for color aware mode; first free other stats ptr except 0, then alloc new and free stats ptr 0 in the end*/
    if(DRV_FROM_TMM(lchip) && p_statsid->type == SYS_STATS_TYPE_ACL && num > 1 && offset == 0)
    {
        sys_usw_opf_free_offset(lchip, &opf, num-1, 1);
        ret = sys_usw_opf_alloc_offset(lchip, &opf, num, &offset);
        sys_usw_opf_free_offset(lchip, &opf, 1, 0);
        CTC_ERROR_RETURN(ret);
    }
    SYS_STATS_DBG_INFO("dir:%d, ram:%d, offset:%u.\n",p_statsid->dir, opf.pool_index, offset);
    /*if(p_statsid->type == SYS_STATS_TYPE_NPM_IM && p_statsid->dir == CTC_EGRESS)
    {
        STATS_SHARE_NPM_PTR(p_statsid)->egs_stats_ptr = SYS_STATS_ENCODE_SYS_PTR(opf.pool_index, offset);
        SYS_STATS_DBG_INFO("alloc flow stats egress stats_ptr:0x%04X\n", STATS_SHARE_NPM_PTR(p_statsid)->egs_stats_ptr);
    }
    else*/
    {
        p_statsid->ptr = SYS_STATS_ENCODE_SYS_PTR(opf.pool_index, offset);
    }
    SYS_STATS_DBG_INFO("alloc flow stats stats_ptr:0x%04X\n", p_statsid->ptr);

    p_ram->used_cnt += num;
    p_prop->used_cnt += num;
    p_prop->used_cnt_ram[opf.pool_index] += num;
    usw_flow_stats_master[lchip]->alloc_count += num;

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_free_statsptr(uint8 lchip, sys_stats_param_t* p_statsid)
{
    sys_usw_opf_t opf;
    sys_stats_ram_prop_t* p_ram = NULL;
    sys_stats_prop_t* p_prop = NULL;
    uint32  stats_ptr = 0;
    uint16 num = p_statsid->num;

    SYS_STATS_DBG_FUNC();
    CTC_MIN_VALUE_CHECK(num, 1);

    stats_ptr = p_statsid->ptr;
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type = usw_flow_stats_master[lchip]->opf_type_flow_stats;
    opf.pool_index = SYS_STATS_DECODE_PTR_RAM(stats_ptr);

    SYS_STATS_DBG_INFO("free flow stats_ptr:0x%08X, ram:%u, index:%u\n",
                       stats_ptr, opf.pool_index, SYS_STATS_DECODE_PTR_OFFSET(stats_ptr));
    CTC_ERROR_RETURN(sys_usw_opf_free_offset(lchip, &opf, num, SYS_STATS_DECODE_PTR_OFFSET(stats_ptr)));

    p_prop = &(usw_flow_stats_master[lchip]->stats_type[p_statsid->dir][p_statsid->type]);
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[opf.pool_index]);
    p_ram->used_cnt -= num;
    p_prop->used_cnt -= num;
    p_prop->used_cnt_ram[opf.pool_index] -= num;
    usw_flow_stats_master[lchip]->alloc_count -= num;
    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_restore_statsptr(uint8 lchip, uint8 stats_num, uint8 dir, uint8 stats_type, uint32 stats_ptr )
{
    int32 ret = CTC_E_NONE;
    sys_usw_opf_t opf;
    uint32 offset = 0;
    uint32 temp_stats_ptr = 0;

    SYS_STATS_DBG_FUNC();
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type = usw_flow_stats_master[lchip]->opf_type_flow_stats;
    opf.pool_index = _sys_usw_flow_stats_decode_hw_ptr(lchip, stats_type, dir, stats_ptr);
    offset = DRV_IS_DUET2(lchip)?(stats_ptr)&0xFFF:(stats_ptr)&0x1FFF;
    ret = sys_usw_opf_alloc_offset_from_position(lchip, &opf, stats_num, offset);
    if (ret != CTC_E_NONE)
    {
        SYS_STATS_DBG_ERROR(" [Stats] statsptr already in used \n");
        return ret;
    }
    temp_stats_ptr = SYS_STATS_ENCODE_SYS_PTR(opf.pool_index, DRV_IS_DUET2(lchip)?(stats_ptr)&0xFFF:(stats_ptr)&0x1FFF);
    ret = _sys_usw_flow_stats_entry_create(lchip, stats_num, 0, temp_stats_ptr);
    if (ret)
    {
        sys_usw_opf_free_offset(lchip, &opf, stats_num, offset);
        SYS_STATS_DBG_ERROR(" [Stats] Stats create entry failed \n");
        return ret;
    }
    usw_flow_stats_master[lchip]->stats_type[dir][stats_type].used_cnt +=stats_num;
    usw_flow_stats_master[lchip]->stats_type[dir][stats_type].used_cnt_ram[opf.pool_index]+=stats_num;
    usw_flow_stats_master[lchip]->p_stats_ram[opf.pool_index].used_cnt +=stats_num;
    usw_flow_stats_master[lchip]->alloc_count +=stats_num;
    return ret;
}

#define __4_FLOW_STATS__

STATIC int32
_sys_usw_flow_stats_get_stats(uint8 lchip, uint32 stats_ptr, uint16 num, ctc_stats_basic_t* p_count)
{
    uint16 i = 0;
    uint8 ram = 0;
    uint32 stats_idx = 0;
    uint32 tmp_ptr = 0;
    sys_stats_ram_prop_t* p_ram = NULL;
    sys_stats_flow_stats_t* p_fwd_stats = NULL;
    ctc_stats_basic_t* p_cnt = NULL;
    uint8 from_tmm = DRV_FROM_TMM(lchip);
    uint8 pp_base = SYS_PP_BASE(lchip);
    uint8 pp_num = SYS_PP_NUM(lchip);
    uint8 temp_lchip = 0;
    uint8 loop_num = 0;

    SYS_STATS_DBG_FUNC();
    SYS_STATS_INIT_CHECK();
    CTC_PTR_VALID_CHECK(p_count);
    CTC_MIN_VALUE_CHECK(num, 1);

    sal_memset(p_count, 0, sizeof(ctc_stats_basic_t) * num);

    for (i=0; i<num; i++)
    {
        tmp_ptr = stats_ptr + i;
        p_cnt = p_count + i;

        CTC_ERROR_RETURN(_sys_usw_flow_stats_entry_lookup(lchip, tmp_ptr, &p_fwd_stats));

        ram = SYS_STATS_DECODE_PTR_RAM(tmp_ptr);
        if (from_tmm || ram != SYS_STATS_RAM_SDC)
        {
            p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[ram]);
            stats_idx = p_ram->base_idx + SYS_STATS_DECODE_PTR_OFFSET(tmp_ptr);
            /* global ram need read all pp count */
            temp_lchip = p_ram->pp_en ? lchip : pp_base;
            loop_num = p_ram->pp_en ? 1 : pp_num;
            do
            {
                CTC_ERROR_RETURN(_sys_usw_flow_stats_read_count(temp_lchip, stats_idx, ram, p_cnt));
                /*for at fifo sync, need after read count*/
                SYS_STATS_SYNC_FIFO(temp_lchip)
                temp_lchip++;
            }
            while (temp_lchip < (loop_num + pp_base));
        }

        if (NULL != p_fwd_stats)
        {
            if (usw_flow_stats_master[lchip]->clear_read_en || (!from_tmm && ram == SYS_STATS_RAM_SDC))
            {
                p_fwd_stats->packet_count += p_cnt->packet_count;
                p_fwd_stats->byte_count += p_cnt->byte_count;

                p_cnt->packet_count = p_fwd_stats->packet_count;
                p_cnt->byte_count = p_fwd_stats->byte_count;
            }
            else
            {
                p_fwd_stats->packet_count = p_cnt->packet_count;
                p_fwd_stats->byte_count = p_cnt->byte_count;
            }
        }

        SYS_STATS_DBG_INFO("stats_ptr:0x%08X, stats_idx:0x%08X, packets:%"PRIu64", bytes:%"PRIu64"\n",
                           tmp_ptr, stats_idx, p_cnt->packet_count, p_cnt->byte_count);
    }

    return CTC_E_NONE;

}


STATIC int32
_sys_usw_flow_stats_clear_stats(uint8 lchip, uint16 num, uint32 stats_ptr)
{
    uint16 i = 0;
    ds_t   ds = {0};
    uint32 cmd = 0;
    uint8  ram = 0;
    uint32 stats_idx = 0;
    uint32 tmp_ptr = 0;
    uint32 tbl_id = DsStats_t;
    uint32 entry_num = 0;
    ctc_stats_basic_t count;
    sys_stats_ram_prop_t* p_ram = NULL;
    sys_stats_flow_stats_t* p_fwd_stats = NULL;
    uint8 pp_base = SYS_PP_BASE(lchip);
#ifdef EMULATION_ENV
    uint8 pp_num = 2;
#else
    uint8 pp_num = SYS_PP_NUM(lchip);
#endif
    uint32* dma_data[SYS_DMA_FLOW_STATS_DESC_DEPTH*32];
    uint8   dma_done[SYS_DMA_FLOW_STATS_DESC_DEPTH*32];
    uint16 data_base = 0;
    uint16 data_step = 1;
    uint8* hw_stats = NULL;
    uint8 loop2 = 0;
    uint8 temp_lchip = 0;
    uint8 loop_num = 1;
    uint8 offset_bytes = 0;
    uint8 stats_type = 0;
    uint8 queue_base = MCHIP_CAP(SYS_CAP_ACL_EGRESS_LKUP_NUM) + MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM) + MCHIP_CAP(SYS_CAP_STATS_GLOBAL_RAM_NUM);

    SYS_STATS_DBG_FUNC();
    SYS_STATS_INIT_CHECK();
    CTC_MIN_VALUE_CHECK(num, 1);
    SYS_STATS_DBG_INFO("stats_ptr:0x%08X\n", stats_ptr);

    if(SYS_STATS_DECODE_PTR_RAM(stats_ptr) == SYS_STATS_RAM_QUE)
    {
        /*bit 14&15 for queue stats packet type*/
        stats_type = stats_ptr >> SYS_QUEUE_STATS_PTR_PKT_TYPE_SHIFT & 0x3;
        CTC_BIT_UNSET(stats_ptr, SYS_QUEUE_STATS_PTR_PKT_TYPE_SHIFT);
        CTC_BIT_UNSET(stats_ptr, SYS_QUEUE_STATS_PTR_PKT_TYPE_SHIFT + 1);
    }
    for (i=0; i<num; i++)
    {
        tmp_ptr = stats_ptr+i;
        sal_memset(&count, 0, sizeof(ctc_stats_basic_t));
        CTC_ERROR_RETURN(_sys_usw_flow_stats_entry_lookup(lchip, tmp_ptr, &p_fwd_stats));
        if (NULL == p_fwd_stats)
        {
            return CTC_E_NONE;
        }
        SYS_STATS_DBG_INFO("clear stats_ptr:0x%08X stats db.\n", tmp_ptr);

        ram = SYS_STATS_DECODE_PTR_RAM(tmp_ptr);
        p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[ram]);
        drv_usw_ftm_get_flow_stats_table_id(lchip, ram, &tbl_id);
        if (DRV_FROM_TMM(lchip) || ram != SYS_STATS_RAM_SDC)
        {
            stats_idx = p_ram->base_idx + SYS_STATS_DECODE_PTR_OFFSET(tmp_ptr);
            temp_lchip = p_ram->pp_en ? lchip : pp_base;
            loop_num = p_ram->pp_en ? 1 : pp_num;
            /* cache may contain count but not reach threshold, may influence next stats, for D2/TM */
            if (!DRV_FROM_TMM(lchip))
            {
                cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(temp_lchip, SYS_STATS_DECODE_PTR_OFFSET(tmp_ptr), DRV_CMD_PP_EN(cmd), &ds));
            }
            do
            {
                CTC_ERROR_RETURN(_sys_usw_flow_stats_read_count(temp_lchip, stats_idx, ram, &count));
                SYS_STATS_SYNC_FIFO(temp_lchip)
                temp_lchip++;
            }
            while (temp_lchip < (loop_num + pp_base));
        }
        if (usw_flow_stats_master[lchip]->clear_read_en)
        {
            p_fwd_stats->packet_count += count.packet_count;
            p_fwd_stats->byte_count += count.byte_count;
        }
        else
        {
            p_fwd_stats->packet_count = count.packet_count;
            p_fwd_stats->byte_count = count.byte_count;
        }

        /*clear the stats in the dma memory*/
        offset_bytes = (DRV_FROM_TMM(lchip) && (ram < queue_base))?16:8;
        /* check fifo sync mode, if fifo sync, only process queue stats */
        if ((sys_usw_dma_get_flow_stats_sync_mode(lchip) && ram != SYS_STATS_RAM_SDC) || (DRV_FROM_AT(lchip) && ram >= queue_base ))
        {
            sys_usw_dma_get_flow_stats_memory(lchip, ram,  dma_data, dma_done);
            if (DRV_FROM_AT(lchip) && MEM_TYPE_PEER_DP == TABLE_ENTRY_TYPE(lchip, tbl_id))
            {
                entry_num = DRV_TABLE_MAX_INDEX(lchip, tbl_id)/2;
                data_step = SYS_VCHIP_DUAL_CORE_MODE(lchip)?4:2; /* peer dp tbl, ram : dsc = 1:N ,if DUAL_CORE_MODE, N = 4,else N = 2 */
            }
            else if (DRV_FROM_AT(lchip) && MEM_TYPE_PER_DP == TABLE_ENTRY_TYPE(lchip, tbl_id))
            {
                entry_num = DRV_TABLE_MAX_INDEX(lchip, tbl_id);
                data_step = 2; /* per dp tbl, ram : dsc = 1:2 */
            }
            else
            {
                entry_num = DRV_TABLE_MAX_INDEX(lchip, tbl_id);
            }
            /* if p_ram->pp_en, loop_num == 1, it will cycle in ctc, this only process dma_data of current pp */
            data_base = (p_ram->pp_en ? lchip-pp_base : 0)*data_step + (SYS_STATS_DECODE_PTR_OFFSET(tmp_ptr)/entry_num);

            if (dma_data[0] != NULL)
            {
                loop2 = 0;
                do
                {
                    hw_stats = ((uint8*)(dma_data[loop2*data_step +data_base]) + (SYS_STATS_DECODE_PTR_OFFSET(tmp_ptr) % entry_num) * offset_bytes);                
                    if (DRV_FROM_TMM(lchip) && (ram >= queue_base)
                        && dma_done[loop2*data_step +data_base]
                        && !MCHIP_F_STATS(lchip)->ds2count(lchip, tbl_id, (ds_t*)(hw_stats), &count))
                    {
                        p_fwd_stats->packet_count += count.packet_count;
                        p_fwd_stats->byte_count += count.byte_count;
                    }
                    sal_memset(hw_stats, 0, offset_bytes);
                    loop2++;
                }while(loop2 < (SYS_DMA_FLOW_STATS_DESC_DEPTH * loop_num));
            }
        }
        if (!stats_type || CTC_IS_BIT_SET(stats_type, SYS_QUEUE_STATS_DROP_PKT_SHIFT))
        {
            p_fwd_stats->packet_count = 0;
        }
        if (!stats_type || CTC_IS_BIT_SET(stats_type, SYS_QUEUE_STATS_DEQ_PKT_SHIFT))
        {
            p_fwd_stats->byte_count = 0;
        }
    }
    return CTC_E_NONE;
}

#define __5_STATS_SYNC__
STATIC int32
_sys_usw_flow_stats_sync_sdc_stats(uint8 lchip, void* p_data)
{
    int32 ret = 0;
    uint32 stats_ptr[CTC_BOTH_DIRECTION] = {0};
    uint32 pkt_len[CTC_BOTH_DIRECTION] = {0};
    uint8 valid[CTC_BOTH_DIRECTION] = {0};
    sys_dma_info_t* p_info = NULL;
    DmaToCpuSdcFifo_m* p_sdc = NULL;
    sys_stats_flow_stats_t* p_fwd_stats = NULL;
    uint32 index = 0;
    uint32 stats_ptr_used = 0;
    uint32 pkt_len_used = 0;
    uint8 sub_idx = 0;

    p_info = (sys_dma_info_t*)p_data;

    SYS_STATS_INIT_CHECK();

    for (index = 0; index < p_info->entry_num; index++)
    {
        p_sdc = (DmaToCpuSdcFifo_m*)((uint8*)p_info->p_data + index*TABLE_ENTRY_SIZE(lchip, DmaToCpuSdcFifo_t));

        valid[0] = 0;
        valid[1] = 0;
        if (GetDmaToCpuSdcFifo(V,ipeSdcValid_f, p_sdc))
        {
            stats_ptr[CTC_INGRESS] = GetDmaToCpuSdcFifo(V,ipeSdcPtr_f, p_sdc);
            pkt_len[CTC_INGRESS] = GetDmaToCpuSdcFifo(V,ipeSdcLen_f, p_sdc);
            stats_ptr[CTC_INGRESS] = SYS_STATS_ENCODE_SYS_PTR(SYS_STATS_RAM_SDC, stats_ptr[CTC_INGRESS]);
            valid[CTC_INGRESS] = 1;
        }

        if(GetDmaToCpuSdcFifo(V,epeSdcValid_f, p_sdc))
        {
            stats_ptr[CTC_EGRESS] = GetDmaToCpuSdcFifo(V,epeSdcPtr_f, p_sdc);
            pkt_len[CTC_EGRESS] = GetDmaToCpuSdcFifo(V,epeSdcLen_f, p_sdc);
            stats_ptr[CTC_EGRESS] = SYS_STATS_ENCODE_SYS_PTR(SYS_STATS_RAM_SDC, stats_ptr[CTC_EGRESS]);
            valid[CTC_EGRESS] = 1;
        }

        STATS_LOCK(lchip);

        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_STATSID, 1);
        for (sub_idx = 0; sub_idx < CTC_BOTH_DIRECTION; sub_idx++)
        {
            if (valid[sub_idx])
            {
                stats_ptr_used = stats_ptr[sub_idx];
                pkt_len_used = pkt_len[sub_idx];

                SYS_STATS_DBG_INFO( "Stats_ptr:0x%x \n", stats_ptr_used);
                SYS_STATS_DBG_INFO( "Pkt Len:0x%x \n", pkt_len_used);

                CTC_ERROR_RETURN_UNLOCK(_sys_usw_flow_stats_entry_lookup(lchip, stats_ptr_used, &p_fwd_stats));

                if (NULL != p_fwd_stats)
                {
                    p_fwd_stats->packet_count += 1;
                    p_fwd_stats->byte_count += pkt_len_used;
                }
                else
                {
                    /*add to db*/
                    ret = _sys_usw_flow_stats_entry_create(lchip, 1, 0, stats_ptr_used);
                    if (ret)
                    {
                        continue;
                    }
                    ret = _sys_usw_flow_stats_entry_lookup(lchip, stats_ptr_used, &p_fwd_stats);
                    if (ret || !p_fwd_stats)
                    {
                        CTC_ERROR_DUMP(_sys_usw_flow_stats_entry_delete(lchip, 1, stats_ptr_used));
                        continue;
                    }

                    p_fwd_stats->stats_ptr = stats_ptr_used;
                    p_fwd_stats->packet_count = 1;
                    p_fwd_stats->byte_count = pkt_len_used;
                }
            }
        }

        STATS_UNLOCK(lchip);
    }


    return CTC_E_NONE;

}
STATIC int32
_sys_usw_flow_stats_map_sync_info(uint16 dma_data, uint8* p_lchip, uint32* offset, uint32* offset_end, uint32* offset_num,uint32* p_tbl_id)
{
    uint8 dp_id = 0;
    uint8 pp_id = 0;
    uint16 blkid = 0;
    uint8 lchip = *p_lchip;
    uint8 pp_base = SYS_PP_BASE(lchip);
    uint32 tbl_id = 0;
    uint32 entry_num = 0;

    dp_id = (dma_data >> 8) & 0x3;
    pp_id = dma_data >> 10;
    CTC_MAX_VALUE_CHECK(pp_id, SYS_PP_NUM(lchip)-1);
    blkid = dma_data & 0xff;
    CTC_MAX_VALUE_CHECK(blkid, MCHIP_CAP(SYS_CAP_STATS_RAM_NUM)-1);
    if (!DRV_FROM_TMM(lchip))
    {
        *offset = 1;
        *offset_end = usw_flow_stats_master[lchip]->p_stats_ram[blkid].total_cnt-1;
        *offset_num = usw_flow_stats_master[lchip]->p_stats_ram[blkid].total_cnt;
        *p_tbl_id = DsStats_t;
        return CTC_E_NONE;
    }
    *p_lchip = usw_flow_stats_master[lchip]->p_stats_ram[blkid].pp_en ? (pp_base+pp_id): pp_base;
    drv_usw_ftm_get_flow_stats_table_id(lchip, blkid, &tbl_id);
    switch (blkid)
    {
        case SYS_STATS_RAM_AT_QUE_UC:/* peer dp table*/
        case SYS_STATS_RAM_AT_DMA_UC:/* peer dp table*/
        case SYS_STATS_RAM_AT_PORTTC_UC:/* per dp table*/
        case SYS_STATS_RAM_AT_PORTTC_MC:/* per dp table*/
            entry_num = (MEM_TYPE_PEER_DP == TABLE_ENTRY_TYPE(lchip, tbl_id))
                         ? (DRV_TABLE_MAX_INDEX(lchip, tbl_id) >> 1) : DRV_TABLE_MAX_INDEX(lchip, tbl_id);
            *offset = entry_num*dp_id;
            *offset_end = *offset + entry_num -1;
            *offset_num = entry_num;
            break;

        default:
            *offset = 0;
            *offset_end =DRV_TABLE_MAX_INDEX(lchip, tbl_id) - 1;
            *offset_num = DRV_TABLE_MAX_INDEX(lchip, tbl_id);
            break;
    }

    *p_tbl_id = tbl_id;

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_sync_flow_stats(uint8 lchip, void* p_data)
{
    int32 ret = 0;
    uint16 dma_data = 0;
    uint32 offset = 0;
    uint32 offset_end = 0;
    uint32 offset_num = 0;
    uint32 cnt = 0xffff;
    uint16 blkid = 0;
    uint8* p_addr = NULL;
    sys_stats_flow_stats_t* p_flow_stats = NULL;
    sys_dma_reg_t* p_dma_reg = (sys_dma_reg_t*)p_data;
    DsStats_m* hw_stats = NULL;
    ctc_stats_basic_t sw_count;
    uint32 tbl_id = DsStats_t;
    uint8 offset_bytes = 0;
	uint8 clear_flag = 0;
    uint32 clear_size = 0;

    SYS_STATS_INIT_CHECK();

    dma_data = *((uint16*)p_dma_reg->p_ext);
    p_addr = p_dma_reg->p_data;
    blkid = dma_data & 0xff;

    CTC_ERROR_RETURN(_sys_usw_flow_stats_map_sync_info(dma_data, &lchip, &offset, &offset_end, &offset_num, &tbl_id));

    offset_bytes = (8 == DRV_TABLE_ENTRY_SIZE(lchip, tbl_id)) ?8:16;

    STATS_LOCK(lchip);
    CTC_BMP64_ITER_BEGIN(usw_flow_stats_master[lchip]->statsptr_bmp[blkid].bmp, offset, offset_end);
        p_flow_stats = ctc_vector_get(usw_flow_stats_master[lchip]->flow_stats_vec[blkid], offset);
        if (NULL == p_flow_stats)
        {
            continue;
        }
        sw_count.byte_count = 0;
        sw_count.packet_count = 0;
        hw_stats = (DsStats_m*)((uint8*)p_addr + offset_bytes*(offset%offset_num));
        ret = MCHIP_F_STATS(lchip)->ds2count(lchip, tbl_id, (ds_t*)(hw_stats), &sw_count);
        if (ret)
        {
            SYS_STATS_DBG_ERROR("Dma sync error stats_ptr:0x%04X\n", p_flow_stats->stats_ptr);
        }
        else
        {
            p_flow_stats->packet_count += sw_count.packet_count;
            p_flow_stats->byte_count += sw_count.byte_count;
        }

        if (0 == --cnt)
        {
            break;
        }
    CTC_BMP64_ITER_END(offset);

    clear_flag = DRV_FROM_TMM(lchip) ? (blkid < (MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM)+MCHIP_CAP(SYS_CAP_ACL_EGRESS_LKUP_NUM))) : 1;
    if(clear_flag)
    {
        clear_size = offset_num*offset_bytes;
        sal_memset(p_addr, 0, clear_size);
    }

    STATS_UNLOCK(lchip);
    return CTC_E_NONE;
}

#define __6_STATS_STATSID__
STATIC int32
_sys_usw_flow_stats_id_hash_key_make(sys_stats_statsid_t* statsid)
{
    return statsid->stats_id;
}

STATIC int32
_sys_usw_flow_stats_id_hash_key_cmp(sys_stats_statsid_t* statsid_0, sys_stats_statsid_t* statsid_1)
{
    return (statsid_0->stats_id == statsid_1->stats_id);
}

STATIC int32
_sys_usw_flow_stats_alloc_statsid(uint8 lchip, uint32* p_statsid)
{
    sys_stats_statsid_t  sys_statsid_lkp;
    sys_stats_statsid_t* p_sys_stats_id = NULL;
    sys_usw_opf_t opf;
    uint8 pp_base = SYS_PP_BASE(lchip);

    SYS_STATS_DBG_FUNC();
    SYS_STATS_INIT_CHECK();
    CTC_PTR_VALID_CHECK(p_statsid);

    /*statsid maybe alloc*/
    if (usw_flow_stats_master[lchip]->stats_mode == CTC_STATS_MODE_USER)
    {
        CTC_MIN_VALUE_CHECK((*p_statsid), 1);

        sal_memset(&sys_statsid_lkp, 0, sizeof(sys_statsid_lkp));
        sys_statsid_lkp.stats_id = *p_statsid;
        p_sys_stats_id = ctc_hash_lookup(usw_flow_stats_master[lchip]->flow_stats_id_hash, &sys_statsid_lkp);
        if (p_sys_stats_id != NULL)
        {
            SYS_STATS_DBG_ERROR(" Entry already exist \n");
            return CTC_E_EXIST;
        }
    }
    else
    {
        if(lchip == pp_base)
        {
            sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
            opf.pool_type = usw_flow_stats_master[lchip]->opf_type_stats_id;

            CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(lchip, &opf, 1, p_statsid));
        }
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_free_statsid(uint8 lchip, uint32 stats_id)
{
    sys_usw_opf_t opf;
    uint8 pp_base = SYS_PP_BASE(lchip);

    SYS_STATS_DBG_FUNC();
    SYS_STATS_INIT_CHECK();
    CTC_MIN_VALUE_CHECK(stats_id, 1);

    if (usw_flow_stats_master[lchip]->stats_mode == CTC_STATS_MODE_DEFINE && lchip == pp_base)
    {
        sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
        opf.pool_type = usw_flow_stats_master[lchip]->opf_type_stats_id;
        CTC_ERROR_RETURN(sys_usw_opf_free_offset(lchip, &opf, 1, stats_id));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_create_statsid(uint8 lchip, sys_stats_statsid_acl_t* p_statsid)
{
    int32 ret = CTC_E_NONE;
    uint16 entry_num = 0;
    sys_stats_statsid_t* p_sys_statsid = NULL;
    sys_stats_prop_t* p_prop = NULL;
    uint32 size = 0;
    uint16 ctc_type = 0;

    SYS_STATS_DBG_FUNC();
    size = (SYS_STATS_TYPE_ACL == p_statsid->common.stats_id_type) ? sizeof(sys_stats_statsid_acl_t):
          ((SYS_STATS_TYPE_NPM_IM == p_statsid->common.stats_id_type) ? sizeof(sys_stats_statsid_npm_im_t): sizeof(sys_stats_statsid_t));
    p_sys_statsid = mem_malloc(MEM_STATS_MODULE, size);
    if (p_sys_statsid == NULL)
    {
        SYS_STATS_DBG_ERROR(" No memory \n");
        return CTC_E_NO_MEMORY;
    }
    sal_memset(p_sys_statsid, 0, size);
    CTC_ERROR_GOTO(_sys_usw_flow_stats_alloc_statsid(lchip, &(p_statsid->common.stats_id)),ret, error_roll_0);

    sal_memcpy(p_sys_statsid, p_statsid, sizeof(sys_stats_statsid_t));
    if (SYS_STATS_TYPE_ACL == p_statsid->common.stats_id_type)
    {
        STATS_SHARE_ACL_PTR(p_sys_statsid)->color_aware = p_statsid->color_aware;
        STATS_SHARE_ACL_PTR(p_sys_statsid)->acl_priority = p_statsid->acl_priority;
    }
    else if( SYS_STATS_TYPE_ECMP == p_sys_statsid->stats_id_type ||
             SYS_STATS_TYPE_FID == p_sys_statsid->stats_id_type ||
             SYS_STATS_TYPE_HECMP == p_sys_statsid->stats_id_type )
    {
        if(SYS_STATS_TYPE_ECMP == p_sys_statsid->stats_id_type || SYS_STATS_TYPE_HECMP == p_sys_statsid->stats_id_type)
        {
            uint8 hecmp_en = usw_flow_stats_master[lchip]->hecmp_en;
            uint16 half_num = 0;
            ctc_type = CTC_STATS_ECMP_STATS;
            entry_num = usw_flow_stats_master[lchip]->max_ecmp_num;
            half_num = entry_num>>hecmp_en;
            entry_num = (SYS_STATS_TYPE_ECMP == p_sys_statsid->stats_id_type ) ? (half_num+hecmp_en) : (hecmp_en ? half_num : 0);
        }
        else
        {
            ctc_type = CTC_STATS_FID_STATS;
            entry_num = (MCHIP_CAP(SYS_CAP_SPEC_MAX_FID)+1);
        }
        if (!SYS_STATS_TYPE_ENABLE(ctc_type) )
        {
            SYS_STATS_DBG_ERROR(" Stats not support \n");
            ret = CTC_E_NOT_SUPPORT;
            goto error_roll_1;
        }
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[p_statsid->common.dir][p_sys_statsid->stats_id_type]);
        if(p_prop->used_cnt < entry_num && p_prop->ram_bmp)
        {
            p_prop->used_cnt++;
        }
        else
        {
            ret = CTC_E_NO_RESOURCE;
            goto error_roll_1;
        }
    }

    /*statsid and stats sw*/
    ctc_hash_insert(usw_flow_stats_master[lchip]->flow_stats_id_hash, p_sys_statsid);

    return ret;

error_roll_1:
    _sys_usw_flow_stats_free_statsid(lchip, p_statsid->common.stats_id);
error_roll_0:
    mem_free(p_sys_statsid);
    return ret;
}

STATIC int32
_sys_usw_flow_stats_destroy_statsid(uint8 lchip, uint32 stats_id)
{
    sys_stats_statsid_t* p_statsid_rse = NULL;
    sys_stats_param_t sts_param;
    sys_stats_statsid_t statsid;

    SYS_STATS_DBG_FUNC();

    sal_memset(&sts_param, 0, sizeof(sts_param));
    sal_memset(&statsid, 0, sizeof(statsid));
    statsid.stats_id = stats_id;

    p_statsid_rse = ctc_hash_lookup(usw_flow_stats_master[lchip]->flow_stats_id_hash, &statsid);
    if (p_statsid_rse == NULL)
    {
        SYS_STATS_DBG_ERROR(" Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    sts_param.type = p_statsid_rse->stats_id_type;
    sts_param.dir = p_statsid_rse->dir;
    sts_param.ptr = p_statsid_rse->stats_ptr;
    sts_param.num = ((p_statsid_rse->stats_id_type == SYS_STATS_TYPE_ACL) && STATS_SHARE_ACL_PTR(p_statsid_rse)->color_aware ? 3:
                     (p_statsid_rse->stats_id_type == SYS_STATS_TYPE_NPM_IM) ? 2 : 1);
    if(STATS_SHARE_NPM_FLD(p_statsid_rse, egs_stats_ptr) == 0xFFFF)
    {
        sts_param.num = 1;
    }
    if (p_statsid_rse->stats_ptr_valid)
    {
        _sys_usw_flow_stats_clear_stats(lchip, sts_param.num, p_statsid_rse->stats_ptr);
    }

    if( SYS_STATS_TYPE_ECMP == p_statsid_rse->stats_id_type || 
        SYS_STATS_TYPE_HECMP == p_statsid_rse->stats_id_type || 
        SYS_STATS_TYPE_FID == p_statsid_rse->stats_id_type)
    {
        usw_flow_stats_master[lchip]->stats_type[p_statsid_rse->dir][p_statsid_rse->stats_id_type].used_cnt--;
        if (p_statsid_rse->stats_ptr_valid)
        {
            CTC_ERROR_RETURN(_sys_usw_flow_stats_entry_delete(lchip, sts_param.num, sts_param.ptr));
        }
    }
    else if(p_statsid_rse->stats_ptr_valid)
    {
        CTC_ERROR_RETURN(_sys_usw_flow_stats_free_statsptr(lchip, &sts_param));
        CTC_ERROR_RETURN(_sys_usw_flow_stats_entry_delete(lchip, sts_param.num, sts_param.ptr));
    }

    if(SYS_STATS_TYPE_NPM_IM == p_statsid_rse->stats_id_type && STATS_SHARE_NPM_PTR(p_statsid_rse)->egs_stats_ptr_valid)
    {
        sts_param.dir = CTC_EGRESS;
        sts_param.ptr = STATS_SHARE_NPM_PTR(p_statsid_rse)->egs_stats_ptr;
        CTC_ERROR_RETURN(_sys_usw_flow_stats_free_statsptr(lchip, &sts_param));
        CTC_ERROR_RETURN(_sys_usw_flow_stats_entry_delete(lchip, sts_param.num, sts_param.ptr));
    }
    ctc_hash_remove(usw_flow_stats_master[lchip]->flow_stats_id_hash, p_statsid_rse);
    mem_free(p_statsid_rse);

    CTC_ERROR_RETURN(_sys_usw_flow_stats_free_statsid(lchip, stats_id));

    return CTC_E_NONE;
}

#define __7_STATS_WB__
STATIC int32
_sys_usw_flow_stats_wb_sync_statsid(sys_stats_statsid_t *p_statsid, void *user_data)
{
    uint32 max_entry_cnt = 0;
    sys_wb_stats_statsid_t* p_wb_statsid = NULL;
    sys_traverse_t *data = (sys_traverse_t *)user_data;
    ctc_wb_data_t *wb_data = (ctc_wb_data_t *)(data->data);

    max_entry_cnt = wb_data->buffer_len / (wb_data->key_len + wb_data->data_len);

    p_wb_statsid = (sys_wb_stats_statsid_t *)wb_data->buffer + wb_data->valid_cnt;

    p_wb_statsid->stats_id = p_statsid->stats_id;
    p_wb_statsid->stats_ptr = p_statsid->stats_ptr;
    p_wb_statsid->stats_id_type = p_statsid->stats_id_type;
    p_wb_statsid->dir = p_statsid->dir;
    p_wb_statsid->color_aware = STATS_SHARE_ACL_FLD(p_statsid, color_aware);
    p_wb_statsid->acl_priority = STATS_SHARE_ACL_FLD(p_statsid, acl_priority);
    p_wb_statsid->stats_ptr_valid = p_statsid->stats_ptr_valid;
    p_wb_statsid->egs_stats_ptr_valid = STATS_SHARE_NPM_FLD(p_statsid, egs_stats_ptr_valid);
    p_wb_statsid->egs_stats_ptr = STATS_SHARE_NPM_FLD(p_statsid, egs_stats_ptr);
    p_wb_statsid->rsv = 0;

    wb_data->valid_cnt++;

    if (wb_data->valid_cnt == max_entry_cnt)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(wb_data));
        wb_data->valid_cnt = 0;

    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_wb_sync(uint8 lchip,uint32 app_id)
{
    uint32 type = 0;
    uint32 ram = 0;
    uint8 dir = CTC_INGRESS;
    int32 ret = CTC_E_NONE;
    ctc_wb_data_t wb_data = {0};
    sys_traverse_t user_data = {0};
    sys_wb_stats_master_t  *p_wb_stats_master = NULL;
    uint8 ram_num = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);

    CTC_WB_ALLOC_BUFFER(&wb_data.buffer);

    STATS_LOCK(lchip);
    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_STATS_SUBID_MASTER)
    {
        /*syncup master*/
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_stats_master_t, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_MASTER);
        p_wb_stats_master = (sys_wb_stats_master_t  *)wb_data.buffer;
        p_wb_stats_master->lchip = lchip;
        p_wb_stats_master->version = SYS_WB_VERSION_STATS;

        for (dir = 0; dir < CTC_BOTH_DIRECTION; dir++)
        {
            for ( type = 0; type < SYS_STATS_TYPE_MAX; type++)
            {
                p_wb_stats_master->stats_type[dir][type].ram_bmp = usw_flow_stats_master[lchip]->stats_type[dir][type].ram_bmp;
            }
        }

        for ( ram = 0; ram < ram_num; ram++)
        {
            p_wb_stats_master->stats_ram[ram].stats_bmp[CTC_INGRESS] = usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[CTC_INGRESS];
            p_wb_stats_master->stats_ram[ram].stats_bmp[CTC_EGRESS] = usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[CTC_EGRESS];
            p_wb_stats_master->stats_ram[ram].acl_priority = usw_flow_stats_master[lchip]->p_stats_ram[ram].acl_priority;
            p_wb_stats_master->stats_ram[ram].scl_bmp = usw_flow_stats_master[lchip]->p_stats_ram[ram].scl_bmp;
            p_wb_stats_master->stats_ram[ram].rsv = 0;
        }

        wb_data.valid_cnt = 1;
        CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_MASTER);
    }

     if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_STATS_SUBID_STATSID)
     {
         /*syncup statsid*/
         CTC_WB_INIT_DATA_T((&wb_data), sys_wb_stats_statsid_t, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_STATSID);
         sal_memset(&user_data, 0, sizeof(user_data));
         user_data.data = &wb_data;
         user_data.value1 = lchip;
         wb_data.valid_cnt = 0;

         CTC_ERROR_GOTO(ctc_hash_traverse(usw_flow_stats_master[lchip]->flow_stats_id_hash, (hash_traversal_fn) _sys_usw_flow_stats_wb_sync_statsid, (void *)&user_data), ret, done);
         if (wb_data.valid_cnt > 0)
         {
             CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
             wb_data.valid_cnt = 0;
         }
         CTC_WB_SYNC_END_DATA(CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_STATSID);
     }

done:
    STATS_UNLOCK(lchip);
    CTC_WB_FREE_BUFFER(wb_data.buffer);

    return ret;
}

uint16
sys_usw_flow_stats_get_ram_status(uint8 lchip, void* p_data)
{
    uint32 ram_id = *(uint32*)p_data;

    return usw_flow_stats_master[lchip]->p_stats_ram[ram_id].used_cnt;
}

STATIC int32
_sys_usw_flow_stats_wb_restore_create_statsid_ptr(uint8 lchip, sys_stats_statsid_t* p_sys_statsid)
{
    int32 ret = CTC_E_NONE;
    sys_usw_opf_t opf;
    uint16 stats_num = 0;
    uint32 offset = 0;

    if (DRV_FROM_TMM(lchip) && !p_sys_statsid->stats_ptr_valid && !p_sys_statsid->stats_ptr &&
        ((SYS_STATS_TYPE_NPM_IM == p_sys_statsid->stats_id_type) ? (!STATS_SHARE_NPM_PTR(p_sys_statsid)->egs_stats_ptr_valid
        && !STATS_SHARE_NPM_PTR(p_sys_statsid)->egs_stats_ptr): 1))
    {
        return CTC_E_NONE;
    }

    stats_num = ((SYS_STATS_TYPE_ACL == p_sys_statsid->stats_id_type) && STATS_SHARE_ACL_PTR(p_sys_statsid)->color_aware ? 3:
                 (p_sys_statsid->stats_id_type == SYS_STATS_TYPE_NPM_IM) ? 2 : 1);
    if(STATS_SHARE_NPM_FLD(p_sys_statsid, egs_stats_ptr) == 0xFFFF)
    {
        stats_num = 1;
    }
    if (p_sys_statsid->stats_ptr_valid || p_sys_statsid->stats_ptr & 0x7fffff)
    {
        sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
        opf.pool_type = usw_flow_stats_master[lchip]->opf_type_flow_stats;
        opf.pool_index = SYS_STATS_DECODE_PTR_RAM(p_sys_statsid->stats_ptr);
        offset = SYS_STATS_DECODE_PTR_OFFSET(p_sys_statsid->stats_ptr);
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(lchip, &opf, stats_num, offset));
        ret = _sys_usw_flow_stats_entry_create(lchip, stats_num, p_sys_statsid->stats_id,p_sys_statsid->stats_ptr);
        if (ret)
        {
            sys_usw_opf_free_offset(lchip, &opf, stats_num, offset);
        }
        else
        {
            usw_flow_stats_master[lchip]->stats_type[p_sys_statsid->dir][p_sys_statsid->stats_id_type].used_cnt += stats_num;
            usw_flow_stats_master[lchip]->stats_type[p_sys_statsid->dir][p_sys_statsid->stats_id_type].used_cnt_ram[opf.pool_index] += stats_num;
            usw_flow_stats_master[lchip]->p_stats_ram[opf.pool_index].used_cnt += stats_num;
            usw_flow_stats_master[lchip]->alloc_count += stats_num;
        }
    }

    if (STATS_SHARE_NPM_FLD(p_sys_statsid, egs_stats_ptr_valid) && STATS_SHARE_NPM_FLD(p_sys_statsid, egs_stats_ptr))
    {
        sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
        opf.pool_type = usw_flow_stats_master[lchip]->opf_type_flow_stats;
        opf.pool_index = SYS_STATS_DECODE_PTR_RAM(STATS_SHARE_NPM_PTR(p_sys_statsid)->egs_stats_ptr);
        offset = SYS_STATS_DECODE_PTR_OFFSET(STATS_SHARE_NPM_PTR(p_sys_statsid)->egs_stats_ptr);

        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(lchip, &opf, stats_num, offset));
        ret = _sys_usw_flow_stats_entry_create(lchip, stats_num, p_sys_statsid->stats_id,STATS_SHARE_NPM_PTR(p_sys_statsid)->egs_stats_ptr);
        if (ret)
        {
            sys_usw_opf_free_offset(lchip, &opf, stats_num, offset);
        }
        else
        {
            usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][p_sys_statsid->stats_id_type].used_cnt += stats_num;
            usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][p_sys_statsid->stats_id_type].used_cnt_ram[opf.pool_index] += stats_num;
            usw_flow_stats_master[lchip]->p_stats_ram[opf.pool_index].used_cnt += stats_num;
            usw_flow_stats_master[lchip]->alloc_count += stats_num;
        }
    }

    return ret;
}

STATIC int32
_sys_usw_flow_stats_wb_restore_create_statsid(uint8 lchip, sys_stats_statsid_t* p_sys_statsid)
{
    int32 ret = CTC_E_NONE;
    sys_usw_opf_t opf;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type = usw_flow_stats_master[lchip]->opf_type_stats_id;

    /*statsid maybe alloc*/
    if (usw_flow_stats_master[lchip]->stats_mode != CTC_STATS_MODE_USER)
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(lchip, &opf, 1, p_sys_statsid->stats_id));
    }

    /* stats_ptr from sys_usw_flow_stats_add_ecmp_stats which called by nexthop */
    if ( SYS_STATS_TYPE_ECMP != p_sys_statsid->stats_id_type &&
         SYS_STATS_TYPE_HECMP != p_sys_statsid->stats_id_type &&
         SYS_STATS_TYPE_FID != p_sys_statsid->stats_id_type )
    {
        ret = _sys_usw_flow_stats_wb_restore_create_statsid_ptr(lchip, p_sys_statsid);
        if (ret != CTC_E_NONE)
        {
            if (usw_flow_stats_master[lchip]->stats_mode == CTC_STATS_MODE_DEFINE)
            {
                sys_usw_opf_free_offset(lchip, &opf, 1, p_sys_statsid->stats_id);
            }

            return ret;
        }
    }
    else
    {
        if (p_sys_statsid->stats_ptr || p_sys_statsid->stats_ptr_valid)
        {
            CTC_ERROR_RETURN(_sys_usw_flow_stats_entry_create(lchip, 1, p_sys_statsid->stats_id, p_sys_statsid->stats_ptr));
        }
        usw_flow_stats_master[lchip]->stats_type[p_sys_statsid->dir][p_sys_statsid->stats_id_type].used_cnt++;
    }

    ctc_hash_insert(usw_flow_stats_master[lchip]->flow_stats_id_hash, p_sys_statsid);

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_wb_restore_statsid(uint8 lchip, ctc_wb_query_t* p_wb_query, uint32 version)
{
    int32 ret = CTC_E_NONE;
    uint32 entry_cnt = 0;
    uint32 size = 0;
    sys_wb_stats_statsid_t wb_statsid;
    sys_stats_statsid_t* p_sys_statsid = NULL;

    /*set to default value*/
    sal_memset(&wb_statsid, 0, sizeof(sys_wb_stats_statsid_t));

    CTC_WB_INIT_QUERY_T(p_wb_query, sys_wb_stats_statsid_t, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_STATSID);
    CTC_WB_QUERY_ENTRY_BEGIN(p_wb_query);
    {
        sal_memcpy(&wb_statsid, (uint8*)(p_wb_query->buffer)+entry_cnt*(p_wb_query->key_len + p_wb_query->data_len), p_wb_query->key_len + p_wb_query->data_len);

        entry_cnt++;
        size = (SYS_STATS_TYPE_ACL == wb_statsid.stats_id_type) ? sizeof(sys_stats_statsid_acl_t):
              ((SYS_STATS_TYPE_NPM_IM == wb_statsid.stats_id_type) ? sizeof(sys_stats_statsid_npm_im_t): sizeof(sys_stats_statsid_t));
        p_sys_statsid = mem_malloc(MEM_STATS_MODULE, size);
        if (p_sys_statsid == NULL)
        {
            SYS_STATS_DBG_ERROR(" [Stats] Stats wb restore statsid failed \n");
            continue;
        }
        sal_memset(p_sys_statsid, 0, size);

        p_sys_statsid->stats_id = wb_statsid.stats_id;
        p_sys_statsid->stats_id_type = wb_statsid.stats_id_type;
        p_sys_statsid->stats_ptr = wb_statsid.stats_ptr;
        p_sys_statsid->dir = wb_statsid.dir;
        p_sys_statsid->stats_ptr_valid = wb_statsid.stats_ptr_valid;

        if (SYS_STATS_TYPE_ACL == wb_statsid.stats_id_type)
        {
            STATS_SHARE_ACL_PTR(p_sys_statsid)->color_aware = wb_statsid.color_aware;
            STATS_SHARE_ACL_PTR(p_sys_statsid)->acl_priority = wb_statsid.acl_priority;
        }

        if (SYS_STATS_TYPE_NPM_IM == wb_statsid.stats_id_type)
        {
            STATS_SHARE_NPM_PTR(p_sys_statsid)->egs_stats_ptr_valid = wb_statsid.egs_stats_ptr_valid;
            STATS_SHARE_NPM_PTR(p_sys_statsid)->egs_stats_ptr = wb_statsid.egs_stats_ptr;
        }

        ret = _sys_usw_flow_stats_wb_restore_create_statsid(lchip, p_sys_statsid);
        if (ret)
        {
            mem_free(p_sys_statsid);
            SYS_STATS_DBG_ERROR(" [Stats] Stats wb restore statsid failed \n");
            continue;
        }
    }
    CTC_WB_QUERY_ENTRY_END(p_wb_query);

done:

    return ret;
}

STATIC int32
_sys_usw_flow_stats_wb_restore_master(uint8 lchip, ctc_wb_query_t* p_wb_query, uint32* version)
{
    uint32 type = 0;
    uint32 ram = 0;
    uint8 dir = CTC_INGRESS;
    int32 ret = CTC_E_NONE;
    sys_wb_stats_master_t* p_wb_stats_master = NULL;
    uint8 ram_num = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);


    p_wb_stats_master = (sys_wb_stats_master_t*)mem_malloc(MEM_STATS_MODULE, sizeof(sys_wb_stats_master_t));
    if (NULL == p_wb_stats_master)
    {
        return CTC_E_NO_MEMORY;
    }
    CTC_WB_INIT_QUERY_T(p_wb_query, sys_wb_stats_master_t, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_MASTER);
    CTC_ERROR_GOTO(ctc_wb_query_entry(p_wb_query), ret, done);
    if ((p_wb_query->valid_cnt != 1) || (p_wb_query->is_end != 1))
    {
        CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "query stats master error! valid_cnt: %d, is_end: %d.\n", p_wb_query->valid_cnt, p_wb_query->is_end);
        ret = CTC_E_NONE;
        goto done;
    }

    sal_memset(p_wb_stats_master, 0, sizeof(sys_wb_stats_master_t));
    sal_memcpy(p_wb_stats_master, p_wb_query->buffer, p_wb_query->key_len + p_wb_query->data_len);

    if (CTC_WB_VERSION_CHECK(SYS_WB_VERSION_STATS, p_wb_stats_master->version))
    {
        CTC_ERROR_GOTO(CTC_E_VERSION_MISMATCH, ret, done);
    }

    *version = p_wb_stats_master->version;

    for (dir = 0; dir < CTC_BOTH_DIRECTION; dir++)
    {
        for ( type = 0; type < SYS_STATS_TYPE_MAX; type++)
        {
            usw_flow_stats_master[lchip]->stats_type[dir][type].ram_bmp = p_wb_stats_master->stats_type[dir][type].ram_bmp;
        }
    }

    for ( ram = 0; ram < ram_num; ram++)
    {
        usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[CTC_INGRESS] = p_wb_stats_master->stats_ram[ram].stats_bmp[CTC_INGRESS];
        usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[CTC_EGRESS] = p_wb_stats_master->stats_ram[ram].stats_bmp[CTC_EGRESS];
        usw_flow_stats_master[lchip]->p_stats_ram[ram].acl_priority = p_wb_stats_master->stats_ram[ram].acl_priority;
        usw_flow_stats_master[lchip]->p_stats_ram[ram].scl_bmp = p_wb_stats_master->stats_ram[ram].scl_bmp;
    }
    ret = _sys_usw_flow_stats_ram_alloc(lchip);
done:
    if (p_wb_stats_master)
    {
        mem_free(p_wb_stats_master);
    }

    return ret;
}

STATIC int32
_sys_usw_flow_stats_wb_restore(uint8 lchip)
{
    int32 ret = CTC_E_NONE;
    ctc_wb_query_t wb_query;
    uint32 version = 0;

    SYS_STATS_DBG_FUNC();
    CTC_WB_ALLOC_BUFFER(&wb_query.buffer);

    STATS_LOCK(lchip);

    /*restore  master*/
    CTC_ERROR_GOTO(_sys_usw_flow_stats_wb_restore_master(lchip, &wb_query, &version), ret, done);

    /*restore  statsid*/
    CTC_ERROR_GOTO(_sys_usw_flow_stats_wb_restore_statsid(lchip, &wb_query, version), ret, done);

    SYS_STATS_DBG_INFO( "restore stats ptr alloced num:[%u]\n",usw_flow_stats_master[lchip]->alloc_count);

done:
    if (wb_query.key)
    {
        mem_free(wb_query.key);
    }

   CTC_WB_FREE_BUFFER(wb_query.buffer);

    STATS_UNLOCK(lchip);

    return ret;
}

#define __8_STATS_INIT_FUNC__
STATIC int32
_sys_usw_flow_stats_get_feature_pp_en(uint8 lchip, uint8 stats_type, uint8 dir)
{
    uint8 feature_type = 0xff;
    switch(stats_type)
    {
        case SYS_STATS_TYPE_VLAN:
            feature_type = CTC_FEATURE_VLAN;
            break;

        case SYS_STATS_TYPE_SCL:
            feature_type = CTC_FEATURE_SCL;
            break;

        case SYS_STATS_TYPE_TUNNEL:
            feature_type = (CTC_INGRESS == dir)? CTC_FEATURE_SCL: CTC_FEATURE_NEXTHOP;
            break;

        case SYS_STATS_TYPE_LSP:
        case SYS_STATS_TYPE_PW:
            feature_type = (CTC_INGRESS == dir)? CTC_FEATURE_MPLS: CTC_FEATURE_NEXTHOP;
            break;

        case SYS_STATS_TYPE_FIB:
            feature_type = CTC_FEATURE_IPUC;
            break;

        case SYS_STATS_TYPE_QUEUE_MC:
        case SYS_STATS_TYPE_DMA:
        case SYS_STATS_TYPE_DMA_MC:
        case SYS_STATS_TYPE_QUEUE:
        case SYS_STATS_TYPE_PORTTC:
        case SYS_STATS_TYPE_PORTTC_MC:
        case SYS_STATS_TYPE_POLICER0:
        case SYS_STATS_TYPE_POLICER1:
            feature_type = CTC_FEATURE_QOS;
            break;

        case SYS_STATS_TYPE_ACL:
        case SYS_STATS_TYPE_FLOW_HASH:
            feature_type = CTC_FEATURE_ACL;
            break;

        case SYS_STATS_TYPE_PORT:
        case SYS_STATS_TYPE_MAC:
            feature_type = CTC_FEATURE_PORT;
            break;

        case SYS_STATS_TYPE_FWD_NH:
        case SYS_STATS_TYPE_ECMP:
        case SYS_STATS_TYPE_HECMP:
        case SYS_STATS_TYPE_NSH:
            feature_type = CTC_FEATURE_NEXTHOP;
            break;
        case SYS_STATS_TYPE_NPM_IM:
            feature_type = CTC_FEATURE_NPM;
            break;
        case SYS_STATS_TYPE_VRF:
        case SYS_STATS_TYPE_SDC:
        case SYS_STATS_TYPE_FID:
        case SYS_STATS_TYPE_INTF:
        default:
            return 0;

    }

    return MCHIP_FEATURE_PP_EN(lchip, feature_type);
}

STATIC int32
_sys_usw_flow_stats_determine_pp_ram(uint8 lchip)
{
    uint8 loop;
    uint8 i;
    uint8 j;
    uint32 stats_bmp[CTC_BOTH_DIRECTION] = {0};
    sys_stats_ram_prop_t* p_ram_prop = NULL;

    /* get global stats type bmp by MCHIP_FEATURE_PP_EN */
    for(loop = SYS_STATS_TYPE_QUEUE; loop < SYS_STATS_TYPE_MAX; loop++)
    {
        if(!(_sys_usw_flow_stats_get_feature_pp_en(lchip,loop, CTC_INGRESS)))
        {
            CTC_BIT_SET(stats_bmp[CTC_INGRESS],  loop);
        }
        if(!(_sys_usw_flow_stats_get_feature_pp_en(lchip,loop, CTC_EGRESS)))
        {
            CTC_BIT_SET(stats_bmp[CTC_EGRESS],  loop);
        }
    }

    /* reset global stats type bmp */
    for(loop = SYS_STATS_TYPE_QUEUE; loop < SYS_STATS_TYPE_MAX; loop++)
    {
        for(i = SYS_STATS_RAM_AT_EPE_ACL0; i < SYS_STATS_RAM_AT_NUM; i++)
        {
            p_ram_prop = &(usw_flow_stats_master[lchip]->p_stats_ram[i]);
            for (j = CTC_INGRESS; j < CTC_BOTH_DIRECTION; j++)
            {
                if(0 != (p_ram_prop->stats_bmp[j] & stats_bmp[j]))
                {
                    stats_bmp[j] = p_ram_prop->stats_bmp[j] | stats_bmp[j];
                }
            }
        }
    }
    /* set stats type properity pp_en */
    for(loop = SYS_STATS_TYPE_QUEUE; loop < SYS_STATS_TYPE_MAX; loop++)
    {
        for (j = CTC_INGRESS; j < CTC_BOTH_DIRECTION; j++)
        {
            if (!CTC_IS_BIT_SET(stats_bmp[j], loop))
            {
                usw_flow_stats_master[lchip]->stats_type[j][loop].pp_en = 1;
            }
        }
    }

    /* set stats ram properity pp_en */
    for(i = SYS_STATS_RAM_AT_EPE_ACL0; i < SYS_STATS_RAM_AT_NUM; i++)
    {
        p_ram_prop = &(usw_flow_stats_master[lchip]->p_stats_ram[i]);
        p_ram_prop->pp_en= 1;
        for (j = CTC_INGRESS; j < CTC_BOTH_DIRECTION; j++)
        {
            if(0 != (p_ram_prop->stats_bmp[j] & stats_bmp[j]))
            {
                p_ram_prop->pp_en= 0;
                continue;
            }
        }
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_global_ram_en(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint8 i = 0;
    ds_t ds;
    
    if (!DRV_FROM_TMM(lchip))
    {
        return CTC_E_NONE;
    }
    
    sal_memset(ds, 0, sizeof(ds_t));
    for (i = SYS_STATS_RAM_GLOBAL0; i <= SYS_STATS_RAM_GLOBAL7; i++)
    {
        field_val = usw_flow_stats_master[lchip]->p_stats_ram[i].stats_bmp[CTC_INGRESS]? 1 : 0;
        SetGlobalStatsSel(V, global0StatsIpeSel_f + (i - SYS_STATS_RAM_GLOBAL0), ds, field_val);
    }
    cmd = DRV_IOW(GlobalStatsSel_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), ds));

    sal_memset(ds, 0, sizeof(ds_t));
    for (i = SYS_STATS_RAM_AT_GLOBAL0; i <= SYS_STATS_RAM_AT_GLOBAL7; i++)/*AT*/
    {
        field_val = 1;/*no ram for X-stats*/
        SetGlobalStatsValid(V, epeGlobalStatsX0Valid_f + (i - SYS_STATS_RAM_AT_GLOBAL0), ds, field_val);
    }
    cmd = DRV_IOW(GlobalStatsValid_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), ds));

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_statsid_init(uint8 lchip)
{
    sys_usw_opf_t opf;
    uint32 start_offset = 0;
    uint32 entry_num    = 0;

    usw_flow_stats_master[lchip]->flow_stats_id_hash = ctc_hash_create((MCHIP_CAP(SYS_CAP_STATS_TOTAL_SIZE)/SYS_HASH_SIZE_COMPRESS_RATE_8)/CTC_HASH_2K_BLOCK_SIZE,
                                        CTC_HASH_2K_BLOCK_SIZE,
                                        (hash_key_fn) _sys_usw_flow_stats_id_hash_key_make,
                                        (hash_cmp_fn) _sys_usw_flow_stats_id_hash_key_cmp);

    if (usw_flow_stats_master[lchip]->stats_mode == CTC_STATS_MODE_DEFINE)
    {
        sal_memset(&opf, 0, sizeof(sys_usw_opf_t));

        start_offset  = 1;
        entry_num     = usw_flow_stats_master[lchip]->max_stats_num;
        CTC_ERROR_RETURN(sys_usw_opf_init(lchip, &usw_flow_stats_master[lchip]->opf_type_stats_id, 1, "opf-type-stats-id"));
        opf.pool_type = usw_flow_stats_master[lchip]->opf_type_stats_id;
        CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, start_offset, entry_num));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_global_init(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    ds_t   ds;

    field_val = 1;
    cmd = DRV_IOW(IpeFwdCtl_t, IpeFwdCtl_mcNexthopPtrAsStatsPtrEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));

    field_val = 1;
    cmd = DRV_IOW(IpeAclQosCtl_t, IpeAclQosCtl_mcNexthopPtrAsStatsPtrEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));

    /* After byte/packet reach the threshold, the ram data move to DsStats */
    sal_memset(&ds, 0,sizeof(ds));
    SetStatsUpdateThrdCtl(V, byteThreshold_f,   &ds, SYS_STATS_CHACHE_UPDATE_BYTE_THRESHOLD);
    SetStatsUpdateThrdCtl(V, packetThreshold_f, &ds, SYS_STATS_CHACHE_UPDATE_PKT_THRESHOLD);

    cmd = DRV_IOW(StatsUpdateThrdCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));

    sal_memset(ds, 0, sizeof(ds_t));
    #ifdef EMULATION_ENV
    cmd = DRV_IOR(GlobalStatsSatuInterruptThreshold_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
    #endif
    cmd = DRV_IOR(GlobalStatsSatuInterruptThreshold_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
    SetGlobalStatsSatuInterruptThreshold(V, byteCntThresholdLo_f,         &ds, 0);
    SetGlobalStatsSatuInterruptThreshold(V, byteCntThresholdHi_f,         &ds, 0);
    SetGlobalStatsSatuInterruptThreshold(V, pktCntThresholdLo_f,          &ds, 0);
    SetGlobalStatsSatuInterruptThreshold(V, pktCntThresholdHi_f,          &ds, 0);
    SetGlobalStatsSatuInterruptThreshold(V, satuAddrFifoDepthThreshold_f, &ds, 64);/*AT :default Threshold 64*/
#ifndef EMULATION_ENV
    SetGlobalStatsSatuInterruptThreshold(V, satuAddrFifoDepthThreshold_f, &ds, 0);
#endif

    cmd = DRV_IOW(GlobalStatsSatuInterruptThreshold_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));

    field_val = 1;
    cmd = DRV_IOW(GlobalStatsUpdateEnCtl_t, GlobalStatsUpdateEnCtl_updateEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
    if (!sys_usw_dma_get_flow_stats_sync_mode(lchip))
    {
        cmd = DRV_IOR(GlobalStatsTimeOutCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
        SetGlobalStatsTimeOutCtl(V, timeOutEn_f, &ds, 0);/*enabale*/
        SetGlobalStatsTimeOutCtl(V, timerCfg_f, &ds, 0);
        cmd = DRV_IOW(GlobalStatsTimeOutCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(sys_usw_flow_stats_set_keep_mode(lchip, CTC_STATS_TYPE_FWD, FALSE));
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
    }

    CTC_ERROR_RETURN(sys_usw_flow_stats_set_drop_packet_stats_en(lchip, CTC_STATS_FLOW_DISCARD_STATS, TRUE));
    CTC_ERROR_RETURN(sys_usw_flow_stats_set_saturate_en(lchip, CTC_STATS_TYPE_FWD, FALSE));
    CTC_ERROR_RETURN(sys_usw_flow_stats_set_clear_after_read_en(lchip, CTC_STATS_TYPE_FWD, TRUE));
    CTC_ERROR_RETURN(sys_usw_flow_stats_set_pkt_cnt_threashold(lchip, CTC_STATS_TYPE_FWD, SYS_STATS_DEFAULT_PKT_CNT_THREASHOLD));/*AT_TODO*/
    CTC_ERROR_RETURN(sys_usw_flow_stats_set_byte_cnt_threashold(lchip, CTC_STATS_TYPE_FWD, SYS_STATS_DEFAULT_BYTE_CNT_THREASHOLD));/*AT_TODO*/
    CTC_ERROR_RETURN(sys_usw_flow_stats_set_fifo_interrupt_threashold(lchip, CTC_STATS_TYPE_FWD, SYS_STATS_DEFAULT_FIFO_INTERRUPT_THREASHOLD));/*AT_TODO*/
    return DRV_FROM_TMM(lchip) ? _sys_usw_flow_stats_global_ram_en(lchip) : CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_alloc_fid_type(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 r = 0;
    uint32 stats_ptr = 0;
    uint32 offset = 0;
    sys_stats_prop_t* p_prop = NULL;
    sys_stats_ram_prop_t* p_ram = NULL;
    sys_usw_opf_t opf;
    uint16 total_cnt = 0;
    uint16 used_cnt = 0;
    uint8 dir = 0;
    uint8 flag = 0;
    uint8 ram_id = 0;
    ds1_t ds;
    uint8 ram_num = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type = usw_flow_stats_master[lchip]->opf_type_flow_stats;

    if (SYS_STATS_TYPE_ENABLE(CTC_STATS_FID_STATS))
    {
        sal_memset(&ds, 0, sizeof(ds1_t));
        for (dir = 0; dir < CTC_BOTH_DIRECTION; dir++)
        {
            /* fid stats alloc */
            p_prop = &(usw_flow_stats_master[lchip]->stats_type[dir][SYS_STATS_TYPE_FID]);
            stats_ptr = 0;
            flag = 0;
            total_cnt = 0;
            for (r = 0; r < ram_num; r++)
            {
                p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[r]);
                if (!CTC_IS_BIT_SET(p_ram->stats_bmp[dir], SYS_STATS_TYPE_FID))
                {
                    continue;
                }
                sal_memset(&ds, 0, sizeof(ds1_t));
                opf.pool_index = r;
                used_cnt = p_ram->total_cnt - p_ram->used_cnt - 1;
                used_cnt = ((total_cnt + used_cnt) > (MCHIP_CAP(SYS_CAP_SPEC_MAX_FID) + 1)) ? ((MCHIP_CAP(SYS_CAP_SPEC_MAX_FID) + 1) - total_cnt): used_cnt;
                CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(lchip, &opf, used_cnt, &offset));
                stats_ptr = flag? stats_ptr : _sys_usw_flow_stats_encode_hw_ptr(lchip, r, offset - 1);
                ram_id = flag? ram_id: r;
                flag = 1;
                p_prop->used_cnt_ram[r] += used_cnt;
                p_ram->used_cnt += used_cnt;
                usw_flow_stats_master[lchip]->alloc_count += used_cnt;
                total_cnt += used_cnt;
            }
            if (dir == CTC_INGRESS)
            {
                cmd = DRV_IOR(IpePktProcCtl_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
                SetIpePktProcCtl(V, vsiStatsEn_f, &ds, 1);
                SetIpePktProcCtl(V, fromCflexVsiStatsEn_f, &ds, 0);
                SetIpePktProcCtl(V, spanPktVsiStatsEn_f, &ds, 1);
                SetIpePktProcCtl(V, vsiStatsMin_f, &ds, 1);
                SetIpePktProcCtl(V, vsiStatsMax_f, &ds, MCHIP_CAP(SYS_CAP_SPEC_MAX_FID) + 1);
                SetIpePktProcCtl(V, vsiStatsBase_f, &ds, stats_ptr);
                cmd = DRV_IOW(IpePktProcCtl_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
            }
            else
            {
                cmd = DRV_IOR(EpePktProcCtl_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
                SetEpePktProcCtl(V, vsiStatsEn_f, &ds, 1);
                SetEpePktProcCtl(V, vsiCflexStatsEn_f, &ds, 0x1);/*default not support stacking*/
                SetEpePktProcCtl(V, spanPktVsiStatsEn_f, &ds, 1);
                SetEpePktProcCtl(V, vsiStatsMin_f, &ds, 1);
                SetEpePktProcCtl(V, vsiStatsMax_f, &ds, MCHIP_CAP(SYS_CAP_SPEC_MAX_FID) + 1);
                SetEpePktProcCtl(V, vsiStatsBase_f, &ds, stats_ptr);
                cmd = DRV_IOW(EpePktProcCtl_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
            }
            usw_flow_stats_master[lchip]->fid_base_ptr[dir] = SYS_STATS_ENCODE_SYS_PTR(ram_id, stats_ptr& 0x1FFF);
        }
    }

return CTC_E_NONE;
}

int32
sys_usw_flow_stats_alloc_fid_type(uint8 lchip)
{
    uint8 pp_base = SYS_PP_BASE(lchip);
    uint8 pp_num = SYS_PP_NUM(lchip);

    for(lchip = pp_base; lchip < (pp_base + pp_num); lchip++)
    {
        STATS_LOCK(lchip);
        _sys_usw_flow_stats_alloc_fid_type(lchip);
        STATS_UNLOCK(lchip);
    }

    return CTC_E_NONE;
}


STATIC int32
_sys_usw_flow_stats_alloc_ecmp_stats(uint8 lchip, uint32 num, uint8 hecmp_en)
{
    sys_stats_prop_t* p_prop = NULL;
    sys_stats_ram_prop_t* p_ram = NULL;
    sys_usw_opf_t opf;
    uint32 stats_ptr = 0;    
    uint32 offset = 1;
    uint32 cmd = 0;
    uint32 entry_num = num>>hecmp_en;
    uint8 ram_num = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);     
    uint8 r = 0;
    uint8 i = 0;    

    if(SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        return CTC_E_NONE;
    }
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type = usw_flow_stats_master[lchip]->opf_type_flow_stats;
    i = hecmp_en;
    do{
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_ECMP + i]);
        for (r = 0; r < ram_num; r++)
        {
            p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[r]);
            if (CTC_IS_BIT_SET(p_ram->stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_ECMP + i))
            {
                opf.pool_index = r;
                if(i == 1)/* hecmp */
                {   /*AT*/
                    CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(lchip, &opf, entry_num, &offset));
                    stats_ptr = _sys_usw_flow_stats_encode_hw_ptr(lchip, r, offset - 1);

                    cmd = DRV_IOW(IpeEcmpCtl_t, IpeEcmpCtl_ecmpStage1StatsOffset_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &stats_ptr));
                }
                else
                {
                    if(hecmp_en)
                    {   /* hecmp enable , ecmp grp_id is begin from 2048, ecmp_grp_id 0 is invalid */
                        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(lchip, &opf, entry_num+1, (offset + entry_num)) );
                        entry_num += 1;
                    }
                    else
                    {
                        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(lchip, &opf, entry_num, &offset));
                    }
                    stats_ptr = _sys_usw_flow_stats_encode_hw_ptr(lchip, r, offset - 1);

                    cmd = DRV_IOW(IpeEcmpCtl_t, IpeEcmpCtl_ecmpStage2StatsOffset_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &stats_ptr));
                    /*D2.TM.TMM*/
                    cmd = DRV_IOW(IpeEcmpCtl_t, IpeEcmpCtl_ecmpStatsOffset_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &stats_ptr));
                }
				usw_flow_stats_master[lchip]->ecmp_base_ptr[i] = SYS_STATS_ENCODE_SYS_PTR(r, offset - 1);
                p_prop->used_cnt_ram[r] += entry_num;
                p_ram->used_cnt += entry_num;
                usw_flow_stats_master[lchip]->alloc_count += entry_num;
                break;
            }
        }
    }while(i--);
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_free_ecmp_stats(uint8 lchip, uint32 num, uint8 hecmp_en)
{
    sys_stats_prop_t* p_prop = NULL;
    sys_stats_ram_prop_t* p_ram = NULL;
    sys_usw_opf_t opf;
    uint32 stats_ptr = 0;    
    uint32 offset = 0;
    uint32 entry_num = num >> hecmp_en;
    uint32 cmd = 0;
    uint8 ram_num = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);     
    uint8 r = 0;
    uint8 i = 0;

    if(SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        return CTC_E_NONE;
    }
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type = usw_flow_stats_master[lchip]->opf_type_flow_stats;
    i = hecmp_en;
    do
    {
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_ECMP + i]);
        for (r = 0; r < ram_num; r++)
        {
            p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[r]);
            if (CTC_IS_BIT_SET(p_ram->stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_ECMP+i))
            {
                opf.pool_index = r;
                offset = SYS_STATS_DECODE_PTR_OFFSET(usw_flow_stats_master[SYS_PP_BASE(lchip)]->ecmp_base_ptr[i]) + 1;
                stats_ptr = 0;
                /*AT*/
                if(i==1)
                {
                     CTC_ERROR_RETURN(sys_usw_opf_free_offset(lchip, &opf, entry_num , offset));
                     cmd = DRV_IOW(IpeEcmpCtl_t, IpeEcmpCtl_ecmpStage1StatsOffset_f);
                     CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &stats_ptr));
                }
                else
                {
                    if(hecmp_en)
                    {
                        CTC_ERROR_RETURN(sys_usw_opf_free_offset(lchip, &opf, entry_num+1, offset+entry_num));
                        entry_num += 1;
                    }
                    else
                    {
                         CTC_ERROR_RETURN(sys_usw_opf_free_offset(lchip, &opf, entry_num, offset));
                    }
          
                    cmd = DRV_IOW(IpeEcmpCtl_t, IpeEcmpCtl_ecmpStage2StatsOffset_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &stats_ptr));
                    /*D2.TM.TMM*/
                    cmd = DRV_IOW(IpeEcmpCtl_t, IpeEcmpCtl_ecmpStatsOffset_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &stats_ptr));
                }
                
                usw_flow_stats_master[SYS_PP_BASE(lchip)]->ecmp_base_ptr[i] = 0;
                p_prop->used_cnt_ram[r] -= entry_num;
                p_ram->used_cnt -= entry_num;
                usw_flow_stats_master[lchip]->alloc_count -= entry_num;

                break;
            }
        }
    }while(i--);
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_alloc_solid_type(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 r = 0;
    uint32 stats_ptr = 0;
    uint32 offset = 0;
    sys_stats_prop_t* p_prop = NULL;
    sys_stats_ram_prop_t* p_ram = NULL;
    sys_usw_opf_t opf;
    uint16 entry_num = 0;
    uint8 dir = 0;
    uint32 value = 0;
    ds1_t ds;
    uint8 ram_num = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);

    sal_memset(&ds, 0, sizeof(ds1_t));
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type = usw_flow_stats_master[lchip]->opf_type_flow_stats;

    if (SYS_STATS_TYPE_ENABLE(CTC_STATS_PORT_STATS))
    {
        /* port stats alloc */
        for (dir = 0; dir < CTC_BOTH_DIRECTION; dir++)
        {
            p_prop = &(usw_flow_stats_master[lchip]->stats_type[dir][SYS_STATS_TYPE_PORT]);
            value = p_prop->ram_bmp ? 1 : 0;
            if (dir == CTC_INGRESS)
            {
                cmd = DRV_IOW(IpeFwdStatsCtl_t, IpeFwdStatsCtl_portStatsEn_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value));
                cmd = DRV_IOW(IpeFwdStatsCtl_t, IpeFwdStatsCtl_portStatsPtrBase_f);
            }
            else
            {
                cmd = DRV_IOW(EpeHeaderEditCtl_t, DRV_FROM_TMM(lchip) ? EpeHeaderEditCtl_portStatsEnChanTypeBmp_f : EpeHeaderEditCtl_portStatsEn_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value));
                cmd = DRV_IOW(EpeHeaderEditCtl_t, EpeHeaderEditCtl_portStatsPtrBase_f);
            }

            if(!value)
            {
                continue;
            }

            for (r = 0; r < ram_num; r++)
            {
                p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[r]);

                if (CTC_IS_BIT_SET(p_ram->stats_bmp[dir], SYS_STATS_TYPE_PORT))
                {
                    opf.pool_index = r;
                    CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(lchip, &opf, SYS_USW_MAX_PORT_NUM_PER_CHIP, &offset)); /* only one ram?*/

                    stats_ptr = _sys_usw_flow_stats_encode_hw_ptr(lchip, r, offset);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &stats_ptr));

                    stats_ptr = SYS_STATS_ENCODE_SYS_PTR(r, offset);
                    usw_flow_stats_master[lchip]->port_base_ptr[dir] = SYS_STATS_ENCODE_SYS_PTR(r, stats_ptr);
                    CTC_ERROR_RETURN(_sys_usw_flow_stats_entry_create(lchip, SYS_USW_MAX_PORT_NUM_PER_CHIP, 0, stats_ptr));

                    p_prop->used_cnt_ram[r] += SYS_USW_MAX_PORT_NUM_PER_CHIP;
                    p_ram->used_cnt += SYS_USW_MAX_PORT_NUM_PER_CHIP;
                    usw_flow_stats_master[lchip]->alloc_count += SYS_USW_MAX_PORT_NUM_PER_CHIP;
                    usw_flow_stats_master[lchip]->stats_type[dir][SYS_STATS_TYPE_PORT].used_cnt += SYS_USW_MAX_PORT_NUM_PER_CHIP;
                    break;
                }
            }
        }
    }

    if (SYS_STATS_TYPE_ENABLE(CTC_STATS_ECMP_STATS))
    {
        /* ecmp stats alloc */
        uint8 hecmp_en = usw_flow_stats_master[lchip]->hecmp_en;
        entry_num = usw_flow_stats_master[lchip]->max_ecmp_num;
        hecmp_en = DRV_FROM_AT(lchip) ? hecmp_en : 0;
        CTC_ERROR_RETURN(_sys_usw_flow_stats_alloc_ecmp_stats(lchip, entry_num, hecmp_en));
        MCHIP_CAP(SYS_CAP_SPEC_ECMP_STATS_NUM) = entry_num;
    }

    /*NSH stats*/
    if (DRV_FROM_AT(lchip))
    {
        for (r = 0; r < ram_num; r++)
        {
            p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[r]);

            if (CTC_IS_BIT_SET(p_ram->stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_NSH))
            {

                cmd = DRV_IOR(EpeNextHopCtl_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
                value = _sys_usw_flow_stats_encode_hw_ptr(lchip, r, 3 << 11);/* nsh stats base 6k */
                SetEpeNextHopCtl(V, nshEditStatsBase_f, &ds, value);

                cmd = DRV_IOW(EpeNextHopCtl_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
                break;
            }
        }
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_free_solid_type(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 r = 0;
    uint32 stats_ptr = 0;
    uint32 offset = 0;
    sys_stats_prop_t* p_prop = NULL;
    sys_stats_ram_prop_t* p_ram = NULL;
    sys_usw_opf_t opf;
    uint8 flag = 0;
    uint16 entry_num = 0;
    uint8 dir = 0;
    uint32 value = 0;
    uint8 ram_num = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);
    ds1_t ds;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    sal_memset(&ds, 0, sizeof(ds1_t));
    opf.pool_type = usw_flow_stats_master[lchip]->opf_type_flow_stats;
    /* ecmp stats free */
    if (SYS_STATS_TYPE_ENABLE(CTC_STATS_ECMP_STATS))
    {
        uint8 hecmp_en = usw_flow_stats_master[lchip]->hecmp_en;
        entry_num = usw_flow_stats_master[lchip]->max_ecmp_num;
        hecmp_en = DRV_FROM_AT(lchip) ? hecmp_en : 0;
        _sys_usw_flow_stats_free_ecmp_stats(lchip, entry_num, hecmp_en);
    }

    if (SYS_STATS_TYPE_ENABLE(CTC_STATS_PORT_STATS))
    {
        /* port stats free */
        for (dir = 0; dir < CTC_BOTH_DIRECTION; dir++)
        {
            p_prop = &(usw_flow_stats_master[lchip]->stats_type[dir][SYS_STATS_TYPE_PORT]);

            value = 0;
            if (dir == CTC_INGRESS)
            {
                cmd = DRV_IOW(IpeFwdStatsCtl_t, IpeFwdStatsCtl_portStatsEn_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value));
                cmd = DRV_IOW(IpeFwdStatsCtl_t, IpeFwdStatsCtl_portStatsPtrBase_f);
            }
            else
            {
                cmd = DRV_IOW(EpeHeaderEditCtl_t, DRV_FROM_TMM(lchip) ? EpeHeaderEditCtl_portStatsEnChanTypeBmp_f : EpeHeaderEditCtl_portStatsEn_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value));
                cmd = DRV_IOW(EpeHeaderEditCtl_t, EpeHeaderEditCtl_portStatsPtrBase_f);
            }

            stats_ptr = 0;
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &stats_ptr));

            for (r = 0; r < ram_num; r++)
            {
                p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[r]);

                if (CTC_IS_BIT_SET(p_ram->stats_bmp[dir], SYS_STATS_TYPE_PORT))
                {
                    opf.pool_index = r;
                    offset = SYS_STATS_DECODE_PTR_OFFSET(usw_flow_stats_master[lchip]->port_base_ptr[dir]);
                    CTC_ERROR_RETURN(sys_usw_opf_free_offset(lchip, &opf, SYS_USW_MAX_PORT_NUM_PER_CHIP, offset));

                    usw_flow_stats_master[lchip]->port_base_ptr[dir] = 0;

                    stats_ptr = SYS_STATS_ENCODE_SYS_PTR(r, offset);
                    CTC_ERROR_RETURN(_sys_usw_flow_stats_entry_delete(lchip, SYS_USW_MAX_PORT_NUM_PER_CHIP, stats_ptr));

                    p_prop->used_cnt_ram[r] -= SYS_USW_MAX_PORT_NUM_PER_CHIP;
                    p_prop->used_cnt -= SYS_USW_MAX_PORT_NUM_PER_CHIP;
                    p_ram->used_cnt -= SYS_USW_MAX_PORT_NUM_PER_CHIP;
                    usw_flow_stats_master[lchip]->alloc_count -= SYS_USW_MAX_PORT_NUM_PER_CHIP;
                    break;
                }
            }
        }
    }

    if (SYS_STATS_TYPE_ENABLE(CTC_STATS_FID_STATS))
    {
        sal_memset(&ds, 0, sizeof(ds1_t));
        for (dir = 0; dir < CTC_BOTH_DIRECTION; dir++)
        {
            /* fid stats free */
            flag = 0;
            p_prop = &(usw_flow_stats_master[lchip]->stats_type[dir][SYS_STATS_TYPE_FID]);
            for (r = 0; r < ram_num; r++)
            {
                p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[r]);
                if (CTC_IS_BIT_SET(p_ram->stats_bmp[dir], SYS_STATS_TYPE_FID) && 0 != p_prop->used_cnt_ram[r])
                {
                    sal_memset(&ds, 0, sizeof(ds1_t));
                    opf.pool_index = r;
                    offset = flag? (p_ram->used_cnt - p_prop->used_cnt_ram[r] + 1): SYS_STATS_DECODE_PTR_OFFSET(usw_flow_stats_master[lchip]->fid_base_ptr[dir]) + 1;
                    CTC_ERROR_RETURN(sys_usw_opf_free_offset(lchip, &opf, p_prop->used_cnt_ram[r], offset));
                    p_ram->used_cnt -= p_prop->used_cnt_ram[r];
                    usw_flow_stats_master[lchip]->alloc_count -= p_prop->used_cnt_ram[r];
                    p_prop->used_cnt_ram[r] = 0;
                    flag = 1;
                }
            }
            usw_flow_stats_master[lchip]->fid_base_ptr[dir] = 0;
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_flow_stats_ram_alloc(uint8 lchip)
{
    uint32 base = 0;
    uint32 cmd = 0;
    uint32 r = 0;
    uint32 stats_ptr = 0;
    uint32 offset = 0;
    uint32 total = 0;
    sys_stats_prop_t* p_prop = NULL;
    sys_stats_ram_prop_t* p_ram = NULL;
    sys_usw_opf_t opf;
    uint32 entry_num = 0;
    uint8 ram_num = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);
    SYS_STATS_DBG_FUNC();

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));

    /* global/private stats pool init */
    CTC_ERROR_RETURN(sys_usw_opf_init(lchip, &usw_flow_stats_master[lchip]->opf_type_flow_stats,  ram_num,"opf-type-flow-stats"));

    opf.pool_type = usw_flow_stats_master[lchip]->opf_type_flow_stats;

    for (r = 0; r < ram_num; r++)
    {
        p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[r]);

        opf.pool_index = r;
        if (p_ram->total_cnt > 0)
        {
            if(!DRV_FROM_TMM(lchip))
            {
                /*SDC do not need cache*/
                if (r != SYS_STATS_RAM_SDC)
                {
                    cmd = DRV_IOW(StatsCacheBasePtr_t, p_ram->base_field_id);
                    base = (total>0 ? total-1: 0);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &base));
                    p_ram->base_idx = base;
                    p_ram->base_ptr = SYS_STATS_ENCODE_SYS_PTR(r, 0);

                    SYS_STATS_DBG_INFO( "ram:%-2u, base:0x%08X\n", r, base);

                    total += p_ram->total_cnt;
                }
            }
            if (SYS_STATS_USE_TOTAL_CNT(lchip, r))
            {
                CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, 0, p_ram->total_cnt));
            }
            else
            {
                CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, 1, p_ram->total_cnt - 1));
            }
        }
    }

    /* queue stats alloc */
    if(DRV_IS_DUET2(lchip))
    {
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_QUEUE]);
        CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsStatsQueue_t, &entry_num));
        entry_num--;
        p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_QUEUE]);
        opf.pool_index = SYS_STATS_RAM_QUEUE;
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(lchip, &opf, entry_num, &offset));
        stats_ptr = SYS_STATS_ENCODE_SYS_PTR(SYS_STATS_RAM_QUEUE, 0);
        CTC_ERROR_RETURN(_sys_usw_flow_stats_entry_create(lchip, entry_num, 0, stats_ptr));
        p_prop->used_cnt_ram[SYS_STATS_RAM_QUEUE] += entry_num;
        p_prop->used_cnt += entry_num;
        p_ram->used_cnt += entry_num;
    }

    CTC_ERROR_RETURN(_sys_usw_flow_stats_alloc_solid_type(lchip));

    return CTC_E_NONE;
}


#if defined(DUET2) || defined(TSINGMA)
int32
_sys_usw_flow_stats_type_init(uint8 lchip)
{
    sys_stats_prop_t* p_prop = NULL;

    /*SYS_STATS_TYPE_QUEUE*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_QUEUE]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_QUEUE);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_QUEUE].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_QUEUE);

    /*SYS_STATS_TYPE_VLAN*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_VLAN]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_VLAN);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_VLAN]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_EPE_GLOBAL3);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL3].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_VLAN);

    /*SYS_STATS_TYPE_INTF*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_INTF]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL2);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL2].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_INTF);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_INTF]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_EPE_GLOBAL3);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL3].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_INTF);

    /*SYS_STATS_TYPE_VRF*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_VRF]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_VRF);

    /*SYS_STATS_TYPE_SCL*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_SCL]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_SCL);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_SCL]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_EPE_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL1].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_SCL);

    /*SYS_STATS_TYPE_TUNNEL*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_TUNNEL]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_TUNNEL);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_TUNNEL]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_EPE_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL1].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_TUNNEL);

    /*SYS_STATS_TYPE_LSP*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_LSP]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_LSP);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_LSP]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_EPE_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL1].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_LSP);

    /*SYS_STATS_TYPE_PW*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_PW]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL2);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL2].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_PW);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_PW]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_EPE_GLOBAL2);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL2].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_PW);

    /*SYS_STATS_TYPE_ACL*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_ACL]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_PRIVATE0);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_PRIVATE1);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_PRIVATE2);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_PRIVATE3);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL0);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL1);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL2);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL3);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_PRIVATE0].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_ACL);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_PRIVATE1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_ACL);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_PRIVATE2].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_ACL);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_PRIVATE3].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_ACL);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL0].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_ACL);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_ACL);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL2].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_ACL);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL3].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_ACL);
    usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_PRIVATE0].acl_priority = 0;
    usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_PRIVATE1].acl_priority = 1;
    usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_PRIVATE2].acl_priority = 2;
    usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_PRIVATE3].acl_priority = 3;
    usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL0].acl_priority = 4;
    usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL1].acl_priority = 5;
    usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL2].acl_priority = 6;
    usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL3].acl_priority = 7;
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_ACL]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_EPE_PRIVATE0);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_EPE_GLOBAL0);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_EPE_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_PRIVATE0].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_ACL);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL0].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_ACL);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL1].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_ACL);
    usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_PRIVATE0].acl_priority = 0;
    usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL0].acl_priority = 1;
    usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL1].acl_priority = 2;

    /*SYS_STATS_TYPE_FWD_NH*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_FWD_NH]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL3);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL3].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_FWD_NH);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_FWD_NH]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_EPE_GLOBAL2);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL2].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_FWD_NH);

    /*SYS_STATS_TYPE_FIB*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_FIB]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_FIB);

    /*SYS_STATS_TYPE_FLOW_HASH*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_FLOW_HASH]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL2);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL2].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_FLOW_HASH);

    /*SYS_STATS_TYPE_MAC*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_MAC]);
        CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL3);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL3].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_MAC);


    /*SYS_STATS_TYPE_POLICER0*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_POLICER0]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL0);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL0].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_POLICER0);

    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_POLICER0]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_EPE_GLOBAL0);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL0].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_POLICER0);


    /*SYS_STATS_TYPE_POLICER1*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_POLICER1]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_POLICER1);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_POLICER1]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_EPE_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL1].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_POLICER1);

    if (SYS_STATS_TYPE_ENABLE(CTC_STATS_ECMP_STATS))
    {
        /*SYS_STATS_TYPE_ECMP*/
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_ECMP]);
        CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL3);
        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL3].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_ECMP);
    }

    if (SYS_STATS_TYPE_ENABLE(CTC_STATS_PORT_STATS))
    {
        /*SYS_STATS_TYPE_PORT*/
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_PORT]);
        CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_IPE_GLOBAL3);
        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL3].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_PORT);

        /*SYS_STATS_TYPE_PORT*/
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_PORT]);
        CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_EPE_GLOBAL1);
        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL1].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_PORT);
    }
    /*SYS_STATS_TYPE_SDC*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_SDC]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_SDC);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_SDC].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_SDC);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_SDC]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_SDC);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_SDC].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_SDC);

    return CTC_E_NONE;
}

int32
_sys_usw_flow_stats_ram_init(uint8 lchip)
{
    sys_stats_ram_prop_t* p_ram = NULL;

    /*SYS_STATS_RAM_IPE_GLOBAL0*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL0]);
    if(DRV_IS_DUET2(lchip))
    {
        p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsIngressGlobal0_t)/4*3;/*4096/4*4 = 3071 */
    }
    else
    {
        p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsIngressGlobal0_t)/4*4;/*4096/4*4 = 4096 */
    }
    p_ram->cache_id = DsStatsIngressGlobal0_t;
    p_ram->base_field_id = StatsCacheBasePtr_ipeGlobalStats0BasePtr_f;

    /*SYS_STATS_RAM_IPE_GLOBAL1*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL1]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsIngressGlobal1_t)/4*3;
    p_ram->cache_id = DsStatsIngressGlobal1_t;
    p_ram->base_field_id = StatsCacheBasePtr_ipeGlobalStats1BasePtr_f;

    /*SYS_STATS_RAM_IPE_GLOBAL2*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL2]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsIngressGlobal2_t)/4*3;
    p_ram->cache_id = DsStatsIngressGlobal2_t;
    p_ram->base_field_id = StatsCacheBasePtr_ipeGlobalStats2BasePtr_f;

    /*SYS_STATS_RAM_IPE_GLOBAL3*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL3]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsIngressGlobal3_t)/4*3;
    p_ram->cache_id = DsStatsIngressGlobal3_t;
    p_ram->base_field_id = StatsCacheBasePtr_ipeGlobalStats3BasePtr_f;

    /*SYS_STATS_RAM_EPE_GLOBAL0*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL0]);
    if(DRV_IS_DUET2(lchip))
    {
        p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsEgressGlobal0_t)/2;
    }
    else
    {
        p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsEgressGlobal0_t)/4*4;
    }
    p_ram->cache_id = DsStatsEgressGlobal0_t;
    p_ram->base_field_id = StatsCacheBasePtr_epeGlobalStats0BasePtr_f;

    /*SYS_STATS_RAM_EPE_GLOBAL1*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL1]);
    if(DRV_IS_DUET2(lchip))
    {
        p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsEgressGlobal1_t)/2;
    }
    else
    {
        p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsEgressGlobal1_t)/4*3;
    }
    p_ram->cache_id = DsStatsEgressGlobal1_t;
    p_ram->base_field_id = StatsCacheBasePtr_epeGlobalStats1BasePtr_f;

    /*SYS_STATS_RAM_EPE_GLOBAL2*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL2]);
    if(DRV_IS_DUET2(lchip))
    {
        p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsEgressGlobal2_t)/2;
    }
    else
    {
        p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsEgressGlobal2_t)/4*3;
    }
    p_ram->cache_id = DsStatsEgressGlobal2_t;
    p_ram->base_field_id = StatsCacheBasePtr_epeGlobalStats2BasePtr_f;

    /*SYS_STATS_RAM_EPE_GLOBAL3*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL3]);
    if(DRV_IS_DUET2(lchip))
    {
        p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsEgressGlobal3_t)/2;
    }
    else
    {
        p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsEgressGlobal3_t)/4*2;
    }
    p_ram->cache_id = DsStatsEgressGlobal3_t;
    p_ram->base_field_id = StatsCacheBasePtr_epeGlobalStats3BasePtr_f;

    /*SYS_STATS_RAM_IPE_PRIVATE0*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_PRIVATE0]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsIngressACL0_t);
    p_ram->cache_id = DsStatsIngressACL0_t;
    p_ram->base_field_id = StatsCacheBasePtr_ipePrivateStats0BasePtr_f;

    /*SYS_STATS_RAM_IPE_PRIVATE1*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_PRIVATE1]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsIngressACL1_t);
    p_ram->cache_id = DsStatsIngressACL1_t;
    p_ram->base_field_id = StatsCacheBasePtr_ipePrivateStats1BasePtr_f;

    /*SYS_STATS_RAM_IPE_PRIVATE2*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_PRIVATE2]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsIngressACL2_t);
    p_ram->cache_id = DsStatsIngressACL2_t;
    p_ram->base_field_id = StatsCacheBasePtr_ipePrivateStats2BasePtr_f;

    /*SYS_STATS_RAM_IPE_PRIVATE3*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_PRIVATE3]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsIngressACL3_t);
    p_ram->cache_id = DsStatsIngressACL3_t;
    p_ram->base_field_id = StatsCacheBasePtr_ipePrivateStats3BasePtr_f;

    /*SYS_STATS_RAM_EPE_PRIVATE0*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_PRIVATE0]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsEgressACL0_t);
    p_ram->cache_id = DsStatsEgressACL0_t;
    p_ram->base_field_id = StatsCacheBasePtr_epePrivateStats0BasePtr_f;

    /*SYS_STATS_RAM_QUEUE*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_QUEUE]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsQueue_t);
    p_ram->cache_id = DsStatsQueue_t;
    p_ram->base_field_id = StatsCacheBasePtr_qMgrGlobalStatsBasePtr_f;

    /*SYS_STATS_RAM_SDC*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_SDC]);
    p_ram->total_cnt = 16383;
    p_ram->cache_id = 0;

    //CTC_ERROR_RETURN(_sys_usw_flow_stats_ram_alloc(lchip));

    return CTC_E_NONE;
}


int32
sys_duet2_flow_stats_show_status(uint8 lchip)
{
    uint16 i = 0, j = 0, r = 0;
    char*  igr_desc[SYS_STATS_TYPE_MAX] = {"", "", "", "", "", "","Vlan", "L3if",  "Vrf", "Scl",   "TunnelDecap",  "MplsLspLabel",    "MplsVcLabel",   "Acl", "Forward", "Ip", "Policer0", "Policer1", "Ecmp", "Hecmp", "Port", "FlowHash", "Mac"};
    char*  egr_desc[SYS_STATS_TYPE_MAX] = {"",  "", "", "", "", "" ,"Vlan", "L3if",  "Vrf", "Xlate", "TunnelEncap",  "NexthopMplsLsp",  "NexthopMplsPw", "Acl", "Nexthop", "",     "Policer0", "Policer1", "", "", "Port", "", ""};
    char** p_desc = NULL;
    sys_stats_prop_t* p_prop = NULL;
    sys_stats_ram_prop_t* p_ram = usw_flow_stats_master[lchip]->p_stats_ram;
    LCHIP_CHECK(lchip);
    SYS_STATS_INIT_CHECK();

    SYS_STATS_DBG_DUMP("\n");
    SYS_STATS_DBG_DUMP("Flow Stats Resource Total num:%u, used:%u\n", (uint32)DRV_TABLE_MAX_INDEX(lchip, DsStats_t),usw_flow_stats_master[lchip]->alloc_count);
    SYS_STATS_DBG_DUMP(" --------------------------------------------------------------------------------------------------------------------------------\n");

    for (i = 0; i < CTC_BOTH_DIRECTION; i++)
    {
        p_desc = (CTC_INGRESS == i) ? igr_desc : egr_desc;

        STATS_LOCK(lchip);
        if(i == CTC_INGRESS)
        {
            SYS_STATS_DBG_DUMP(" %-17s%-10s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s\n",
                           "StatsType", "Module", "Global0", "Global1", "Global2", "Global3", "AclRam0", "AclRam1", "AclRam2", "AclRam3", "used-cnt");
            SYS_STATS_DBG_DUMP(" %-27s%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u\n",
                               "max cnt:",
                               p_ram[SYS_STATS_RAM_IPE_GLOBAL0].total_cnt-1 > 0? p_ram[SYS_STATS_RAM_IPE_GLOBAL0].total_cnt-1:0,
                               p_ram[SYS_STATS_RAM_IPE_GLOBAL1].total_cnt-1 > 0? p_ram[SYS_STATS_RAM_IPE_GLOBAL1].total_cnt-1:0,
                               p_ram[SYS_STATS_RAM_IPE_GLOBAL2].total_cnt-1 > 0? p_ram[SYS_STATS_RAM_IPE_GLOBAL2].total_cnt-1:0,
                               p_ram[SYS_STATS_RAM_IPE_GLOBAL3].total_cnt-1 > 0? p_ram[SYS_STATS_RAM_IPE_GLOBAL3].total_cnt-1:0,
                               p_ram[SYS_STATS_RAM_IPE_PRIVATE0].total_cnt-1 > 0? p_ram[SYS_STATS_RAM_IPE_PRIVATE0].total_cnt-1:0,
                               p_ram[SYS_STATS_RAM_IPE_PRIVATE1].total_cnt-1 > 0? p_ram[SYS_STATS_RAM_IPE_PRIVATE1].total_cnt-1:0,
                               p_ram[SYS_STATS_RAM_IPE_PRIVATE2].total_cnt-1 > 0? p_ram[SYS_STATS_RAM_IPE_PRIVATE2].total_cnt-1:0,
                               p_ram[SYS_STATS_RAM_IPE_PRIVATE3].total_cnt-1 > 0? p_ram[SYS_STATS_RAM_IPE_PRIVATE3].total_cnt-1:0);
            SYS_STATS_DBG_DUMP(" %-27s%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u\n",
                               "used cnt:",
                               p_ram[SYS_STATS_RAM_IPE_GLOBAL0].used_cnt,
                               p_ram[SYS_STATS_RAM_IPE_GLOBAL1].used_cnt,
                               p_ram[SYS_STATS_RAM_IPE_GLOBAL2].used_cnt,
                               p_ram[SYS_STATS_RAM_IPE_GLOBAL3].used_cnt,
                               p_ram[SYS_STATS_RAM_IPE_PRIVATE0].used_cnt,
                               p_ram[SYS_STATS_RAM_IPE_PRIVATE1].used_cnt,
                               p_ram[SYS_STATS_RAM_IPE_PRIVATE2].used_cnt,
                               p_ram[SYS_STATS_RAM_IPE_PRIVATE3].used_cnt);

            for (j = SYS_STATS_TYPE_VLAN; j < SYS_STATS_TYPE_SDC; j++)
            {
                if (SYS_STATS_TYPE_FID == j || SYS_STATS_TYPE_NSH == j )
                {
                    continue;
                }
                p_prop = &(usw_flow_stats_master[lchip]->stats_type[i][j]);

                SYS_STATS_DBG_DUMP(" %-17s%-10s", p_desc[j], "Ingress");

                for (r = SYS_STATS_RAM_IPE_GLOBAL0; r < SYS_STATS_RAM_QUEUE; r++)
                {
                    if (!CTC_IS_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[r].stats_bmp[CTC_INGRESS], j))
                    {
                        SYS_STATS_DBG_DUMP("%-9s", "-");
                    }
                    else
                    {
                        SYS_STATS_DBG_DUMP("%-9u", p_prop->used_cnt_ram[r]);
                    }
                }
                for (r = SYS_STATS_RAM_IPE_PRIVATE0; r <= SYS_STATS_RAM_IPE_PRIVATE3; r++)
                {
                    if (!CTC_IS_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[r].stats_bmp[CTC_INGRESS], j))
                    {
                        SYS_STATS_DBG_DUMP("%-9s", "-");
                    }
                    else
                    {
                        SYS_STATS_DBG_DUMP("%-9u", p_prop->used_cnt_ram[r]);
                    }
                }
                SYS_STATS_DBG_DUMP("%-12u", p_prop->used_cnt);

                SYS_STATS_DBG_DUMP("\n");
            }
        }
        else
        {
            SYS_STATS_DBG_DUMP(" %-17s%-10s%-9s%-9s%-9s%-9s%-9s%-9s\n",
                           "StatsType", "Module", "Global0", "Global1", "Global2", "Global3", "AclRam0", "used-cnt");
            SYS_STATS_DBG_DUMP(" %-27s%-9u%-9u%-9u%-9u%-9u\n","max cnt:",
                               p_ram[SYS_STATS_RAM_EPE_GLOBAL0].total_cnt-1 > 0? p_ram[SYS_STATS_RAM_EPE_GLOBAL0].total_cnt-1:0,
                               p_ram[SYS_STATS_RAM_EPE_GLOBAL1].total_cnt-1 > 0? p_ram[SYS_STATS_RAM_EPE_GLOBAL1].total_cnt-1:0,
                               p_ram[SYS_STATS_RAM_EPE_GLOBAL2].total_cnt-1 > 0? p_ram[SYS_STATS_RAM_EPE_GLOBAL2].total_cnt-1:0,
                               p_ram[SYS_STATS_RAM_EPE_GLOBAL3].total_cnt-1 > 0? p_ram[SYS_STATS_RAM_EPE_GLOBAL3].total_cnt-1:0,
                               p_ram[SYS_STATS_RAM_EPE_PRIVATE0].total_cnt-1 > 0? p_ram[SYS_STATS_RAM_EPE_PRIVATE0].total_cnt-1:0);
            SYS_STATS_DBG_DUMP(" %-27s%-9u%-9u%-9u%-9u%-9u\n","used cnt:",
                               p_ram[SYS_STATS_RAM_EPE_GLOBAL0].used_cnt,
                               p_ram[SYS_STATS_RAM_EPE_GLOBAL1].used_cnt,
                               p_ram[SYS_STATS_RAM_EPE_GLOBAL2].used_cnt,
                               p_ram[SYS_STATS_RAM_EPE_GLOBAL3].used_cnt,
                               p_ram[SYS_STATS_RAM_EPE_PRIVATE0].used_cnt);

            for (j = SYS_STATS_TYPE_VLAN; j < SYS_STATS_TYPE_SDC; j++)
            {
                if ((SYS_STATS_TYPE_FIB == j)
                    || (SYS_STATS_TYPE_VRF == j)
                || (SYS_STATS_TYPE_QUEUE == j)
                || (SYS_STATS_TYPE_MAC == j)
                || (SYS_STATS_TYPE_FLOW_HASH == j)
                || (SYS_STATS_TYPE_ECMP == j)
                || (SYS_STATS_TYPE_FID == j)
                || (SYS_STATS_TYPE_NSH == j)
                || (SYS_STATS_TYPE_HECMP == j))
                {
                    continue;
                }
                p_prop = &(usw_flow_stats_master[lchip]->stats_type[i][j]);

                SYS_STATS_DBG_DUMP(" %-17s%-10s", p_desc[j], "Egress");
                for (r = SYS_STATS_RAM_EPE_GLOBAL0; r < SYS_STATS_RAM_IPE_GLOBAL0; r++)
                {
                    if (!CTC_IS_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[r].stats_bmp[CTC_EGRESS], j))
                    {
                        SYS_STATS_DBG_DUMP("%-9s", "-");
                    }
                    else
                    {
                        SYS_STATS_DBG_DUMP("%-9u", p_prop->used_cnt_ram[r]);
                    }
                }
                r = SYS_STATS_RAM_EPE_PRIVATE0;
                if (!CTC_IS_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[r].stats_bmp[CTC_EGRESS], j))
                {
                    SYS_STATS_DBG_DUMP("%-9s", "-");
                }
                else
                {
                    SYS_STATS_DBG_DUMP("%-9u", p_prop->used_cnt_ram[r]);
                }

                SYS_STATS_DBG_DUMP("%-12u", p_prop->used_cnt);
                SYS_STATS_DBG_DUMP("\n");
            }

        }
        STATS_UNLOCK(lchip);
        SYS_STATS_DBG_DUMP(" --------------------------------------------------------------------------------------------------------------------------------\n");

    }
    SYS_STATS_DBG_DUMP("\n");

    return CTC_E_NONE;
}

#endif

#if defined(DUET2)

int32
sys_duet2_flow_stats_ds2count(uint8 lchip, uint32 tbl_id, void* p_ds, ctc_stats_basic_t* p_count)
{
    uint64 value = 0;
    DsStats_d2_s *p_stats = (DsStats_d2_s*)p_ds;
    p_count->packet_count = p_stats->packetCount_27_0;
    value |= p_stats->byteCount_35_4;
    value <<= 4;
    value |= p_stats->byteCount_3_0;
    p_count->byte_count = value;
    return CTC_E_NONE;
}

#endif

#if defined(TSINGMA)

int32
sys_tsingma_flow_stats_ds2count(uint8 lchip, uint32 tbl_id, void* p_ds, ctc_stats_basic_t* p_count)
{
    uint64 value = 0;
    DsStats_tm_s *p_stats = (DsStats_tm_s*)p_ds;
    p_count->packet_count = p_stats->packetCount_27_0;
    value |= p_stats->byteCount_35_4;
    value <<= 4;
    value |= p_stats->byteCount_3_0;
    p_count->byte_count = value;
    return CTC_E_NONE;
}

#endif
#if defined(ARCTIC)
STATIC int32
_sys_at_stats_map_ram_type_drv_to_sys(uint8 drv_type, uint8* sys_type)
{
    if (drv_type <= SYS_STATS_FIFO_SYNC_GLOBAL15)
    {
        *sys_type = SYS_STATS_RAM_AT_GLOBAL0 + drv_type;
    }
    else if (drv_type <= SYS_STATS_FIFO_SYNC_IPE_ACL23)
    {
        *sys_type = SYS_STATS_RAM_AT_IPE_ACL0 + drv_type - SYS_STATS_FIFO_SYNC_IPE_ACL0;
    }
    else if (drv_type <= SYS_STATS_FIFO_SYNC_EPE_ACL11)
    {
        *sys_type = SYS_STATS_RAM_AT_EPE_ACL0 + drv_type - SYS_STATS_FIFO_SYNC_EPE_ACL0;
    }
    return CTC_E_NONE;
}

int32
sys_at_flow_stats_ds2count(uint8 lchip, uint32 tbl_id, void* p_ds, ctc_stats_basic_t* p_count)
{
    uint64 value = 0;

    switch (tbl_id)
    {
    case DsStatsQueueUc_t:
    case DsStatsQueueMc_t:
    case DsStatsDmaUc_t:
    case DsStatsDmaMc_t:
    case DsStatsPortTcUc_t:
    case DsStatsPortTcMc_t:
    {
        DsStatsQueue_at_s *p_stats_queue = (DsStatsQueue_at_s*)p_ds;
        value = p_stats_queue->packetCountEnq_29_0;
        p_count->byte_count = value;
        value = p_stats_queue->packetCountDrop_29_0;
        p_count->packet_count = value;
    }
        break;
    default:
    {
        DsStats_tmm_s *p_stats = (DsStats_tmm_s*)p_ds;
        p_count->packet_count = p_stats->packetCount_29_0;
        value |= p_stats->packetByte_37_34;
        value <<= 32;
        value |= p_stats->packetByte_33_2;
        value <<= 2;
        value |= p_stats->packetByte_1_0;
        p_count->byte_count = value;
    }
        break;
    }
    return CTC_E_NONE;
}

int32
sys_at_flow_stats_sync_fifo_stats(uint8 lchip)
{
    uint32 cmd = 0;
    uint8 i = 0;
    uint8 ram = 0xff;
    uint32 tmp_ptr = 0;
    int32 ret = CTC_E_NONE;
    sys_stats_flow_stats_t* p_fwd_stats = NULL;
    fifo_stats_info_s hw_stats;

    do
    {
        cmd = DRV_IOR(GlobalStatesSatuAddrInfo_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN_WITH_UNLOCK(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &hw_stats), usw_flow_stats_master[lchip]->p_stats_mutex);

        for (i = 0; i < SYS_STATS_SYNC_FIFO_ENTRY_NUM; i++)
        {
            if (!hw_stats.stats_ptr_info[i].valid)
            {
                break;
            }
            _sys_at_stats_map_ram_type_drv_to_sys(hw_stats.stats_ptr_info[i].thrdFifoId , &ram);
            tmp_ptr = SYS_STATS_ENCODE_SYS_PTR(ram, hw_stats.stats_ptr_info[i].statsThrdPtr);
            lchip = usw_flow_stats_master[lchip]->p_stats_ram[ram].pp_en ? lchip : SYS_PP_BASE(lchip);
            ret = _sys_usw_flow_stats_entry_lookup(lchip, tmp_ptr, &p_fwd_stats);
            if (ret)
            {
                SYS_STATS_DBG_ERROR("Fifo sync error stats_ptr:0x%04X, lchip:0x%d\n", tmp_ptr, lchip);
                continue;
            }
            if (hw_stats.stats_ptr_info[i].pktCntFull)
            {
                p_fwd_stats->packet_count += usw_flow_stats_master[lchip]->pkt_cnt_threashold;
            }
            if (hw_stats.stats_ptr_info[i].byteCntFull)
            {
                p_fwd_stats->byte_count += usw_flow_stats_master[lchip]->byte_cnt_threashold;
            }
        }
    }
    while (hw_stats.remainCnt);

    return CTC_E_NONE;
}

int32
sys_at_flow_stats_set_ram_pp_property(uint8 lchip, uint8 dir, uint8 block_id, uint32 lkup_level_bitmap, uint8 is_global)
{
    sys_stats_ram_prop_t* p_ram = NULL;
    uint8 i = 0;
    uint8 start_idx = dir==CTC_INGRESS ? SYS_STATS_RAM_AT_IPE_ACL0: SYS_STATS_RAM_AT_EPE_ACL0;
    uint8 end_idx = dir==CTC_INGRESS ? SYS_STATS_RAM_AT_IPE_ACL23: SYS_STATS_RAM_AT_EPE_ACL11;

    if(!MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL))
    {
        return CTC_E_NONE;
    }
    for (i = start_idx; i <= end_idx; i++)
    {
        p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[i]);

        if(!CTC_IS_BIT_SET(lkup_level_bitmap, p_ram->acl_priority))
        {
            continue;
        }

        p_ram->pp_en = is_global? 0:1;
    }
    return CTC_E_NONE;
}

#endif
#if defined(TSINGMA_MX) || defined(TSINGMA_GX)
int32
sys_tmm_flow_stats_ds2count(uint8 lchip, uint32 tbl_id, void* p_ds, ctc_stats_basic_t* p_count)
{
    uint64 value = 0;
    if (DsStatsQueue_t == tbl_id)
    {
        DsStatsQueue_tmm_s *p_stats_queue = (DsStatsQueue_tmm_s*)p_ds;
        value = p_stats_queue->packetCountEnq_29_0;
        p_count->byte_count = value;
        value = p_stats_queue->packetCountDrop_29_0;
        p_count->packet_count = value;
    }
    else
    {
        DsStats_tmm_s *p_stats = (DsStats_tmm_s*)p_ds;
        p_count->packet_count = p_stats->packetCount_29_0;
        value |= p_stats->packetByte_37_34;
        value <<= 32;
        value |= p_stats->packetByte_33_2;
        value <<= 2;
        value |= p_stats->packetByte_1_0;
        p_count->byte_count = value;
    }
    return CTC_E_NONE;
}
#endif

#if defined(TSINGMA_MX) || defined(TSINGMA_GX) || defined(ARCTIC)
int32
_sys_tmm_flow_stats_ram_init(uint8 lchip)
{
    uint8 ram;
    uint8 stats_ram_num = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);
    uint32 table_id;
    sys_stats_ram_prop_t* p_ram = NULL;
    uint32 entry_num = 0;

    for (ram=0;ram<stats_ram_num;ram++)
    {
        drv_usw_ftm_get_flow_stats_table_id(lchip, ram, &table_id);
        p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[ram]);

        if(ram < SYS_STATS_RAM_AT_QUE_UC)
        {
            entry_num = DRV_TABLE_MAX_INDEX(lchip, table_id);
        }
        else    /* only AT ram may exced SYS_STATS_RAM_AT_QUE_UC */
        {
            sys_usw_ftm_query_table_entry_num(lchip, table_id, &entry_num);
            entry_num = (ram==SYS_STATS_RAM_AT_QUE_UC) ? (entry_num<<1) : entry_num;
        }
        p_ram->total_cnt = entry_num;
        p_ram->cache_id = table_id;
    }

    //CTC_ERROR_RETURN(_sys_usw_flow_stats_ram_alloc(lchip));

    return CTC_E_NONE;
}

#endif
#if defined(TSINGMA_MX) || defined(TSINGMA_GX)

int32
_sys_tmm_flow_stats_type_init(uint8 lchip)
{
    uint8 ram = 0;
    uint8 dir = 2;
    uint8 priority = 0;
    sys_stats_prop_t* p_prop = NULL;

    /*SYS_STATS_TYPE_QUEUE*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_QUEUE]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_QUE);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_QUE].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_QUEUE);

    /*SYS_STATS_TYPE_VLAN*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_VLAN]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_VLAN);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_VLAN]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL7);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL7].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_VLAN);

    /*SYS_STATS_TYPE_INTF*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_INTF]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL2);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL2].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_INTF);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_INTF]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL7);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL7].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_INTF);

    /*SYS_STATS_TYPE_SCL*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_SCL]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_SCL);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_SCL]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL5);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL5].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_SCL);

    /*SYS_STATS_TYPE_TUNNEL*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_TUNNEL]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_TUNNEL);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_TUNNEL]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL5);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL5].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_TUNNEL);

    /*SYS_STATS_TYPE_LSP*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_LSP]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_LSP);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_LSP]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL5);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL5].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_LSP);

    /*SYS_STATS_TYPE_PW*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_PW]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL2);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL2].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_PW);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_PW]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL6);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL6].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_PW);

    /*SYS_STATS_TYPE_FWD_NH*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_FWD_NH]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL3);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL3].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_FWD_NH);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_FWD_NH]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL6);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL6].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_FWD_NH);

    /*SYS_STATS_TYPE_FIB*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_FIB]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_FIB);

    /*SYS_STATS_TYPE_FLOW_HASH*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_FLOW_HASH]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL2);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL2].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_FLOW_HASH);

    /*SYS_STATS_TYPE_MAC*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_MAC]);
        CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL3);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL3].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_MAC);


    /*SYS_STATS_TYPE_POLICER0*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_POLICER0]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL0);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL0].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_POLICER0);

    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_POLICER0]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL4);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL4].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_POLICER0);


    /*SYS_STATS_TYPE_POLICER1*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_POLICER1]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_POLICER1);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_POLICER1]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL5);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL5].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_POLICER1);

     /*SYS_STATS_TYPE_NPM_IM*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_NPM_IM]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL0);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL0].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_NPM_IM);

    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_NPM_IM]);
    CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL4);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL4].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_NPM_IM);

    /*SYS_STATS_TYPE_ACL*/
    for(ram = SYS_STATS_RAM_EPE_ACL0; ram <= SYS_STATS_RAM_IPE_ACL15; ram++)
    {
        dir = (ram < SYS_STATS_RAM_IPE_ACL0) ? CTC_EGRESS : CTC_INGRESS;
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[dir][SYS_STATS_TYPE_ACL]);
        CTC_BIT64_SET(p_prop->ram_bmp, ram);
        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[dir], SYS_STATS_TYPE_ACL);
        priority = (ram < SYS_STATS_RAM_IPE_ACL0) ? (ram-SYS_STATS_RAM_EPE_ACL0) : (ram-SYS_STATS_RAM_IPE_ACL0);
        usw_flow_stats_master[lchip]->p_stats_ram[ram].acl_priority = priority;
    }

    if (SYS_STATS_TYPE_ENABLE(CTC_STATS_ECMP_STATS))
    {
        /*SYS_STATS_TYPE_ECMP*/
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_ECMP]);
        CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL3);
        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL3].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_ECMP);
    }

    if (SYS_STATS_TYPE_ENABLE(CTC_STATS_PORT_STATS))
    {
        /*SYS_STATS_TYPE_PORT*/
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_PORT]);
        CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL3);
        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL3].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_PORT);

        /*SYS_STATS_TYPE_PORT*/
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_PORT]);
        CTC_BIT64_SET(p_prop->ram_bmp, SYS_STATS_RAM_GLOBAL5);
        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_GLOBAL5].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_PORT);
    }
    return CTC_E_NONE;
}

int32
sys_tmm_flow_stats_show_status(uint8 lchip)
{
    uint16 i = 0, j = 0, r = 0;
    char*  igr_desc[SYS_STATS_TYPE_MAX] = {"Vlan", "L3if",  "Vrf", "Scl",   "TunnelDecap",  "MplsLspLabel",    "MplsVcLabel",   "Acl", "Forward", "Ip", "Policer0", "Policer1", "Ecmp", "Hecmp", "Port", "FlowHash", "Mac","","","","Mpls-im"};
    char*  egr_desc[SYS_STATS_TYPE_MAX] = {"Vlan", "L3if",  "Vrf", "Xlate", "TunnelEncap",  "NexthopMplsLsp",  "NexthopMplsPw", "Acl", "Nexthop", "",     "Policer0", "Policer1", "", "", "Port", "", "","","","","Mpls-im"};
    char** p_desc = NULL;
    sys_stats_prop_t* p_prop = NULL;
    sys_stats_ram_prop_t* p_ram = NULL;
    LCHIP_CHECK(lchip);
    SYS_STATS_INIT_CHECK();
    p_ram = usw_flow_stats_master[lchip]->p_stats_ram;

    SYS_STATS_DBG_DUMP("\n");
    SYS_STATS_DBG_DUMP(" ------------------------------------------------------------------------------------------------------------\n");

    for (i = 0; i < CTC_BOTH_DIRECTION; i++)
    {
        p_desc = (CTC_INGRESS == i) ? igr_desc : egr_desc;
        STATS_LOCK(lchip);
        if(i == CTC_INGRESS)
        {
            SYS_STATS_DBG_DUMP(" %-17s%-10s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s\n",
                           "StatsType", "direction", "Global0", "Global1", "Global2", "Global3", "Global4", "Global5", "Global6", "Global7");
            SYS_STATS_DBG_DUMP(" %-27s%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u\n",
                               "max cnt:",
                               p_ram[SYS_STATS_RAM_GLOBAL0].total_cnt-1,
                               p_ram[SYS_STATS_RAM_GLOBAL1].total_cnt-1,
                               p_ram[SYS_STATS_RAM_GLOBAL2].total_cnt-1,
                               p_ram[SYS_STATS_RAM_GLOBAL3].total_cnt-1,
                               p_ram[SYS_STATS_RAM_GLOBAL4].total_cnt-1,
                               p_ram[SYS_STATS_RAM_GLOBAL5].total_cnt-1,
                               p_ram[SYS_STATS_RAM_GLOBAL6].total_cnt-1,
                               p_ram[SYS_STATS_RAM_GLOBAL7].total_cnt-1);
            SYS_STATS_DBG_DUMP(" %-27s%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u\n",
                               "used cnt:",
                               p_ram[SYS_STATS_RAM_GLOBAL0].used_cnt,
                               p_ram[SYS_STATS_RAM_GLOBAL1].used_cnt,
                               p_ram[SYS_STATS_RAM_GLOBAL2].used_cnt,
                               p_ram[SYS_STATS_RAM_GLOBAL3].used_cnt,
                               p_ram[SYS_STATS_RAM_GLOBAL4].used_cnt,
                               p_ram[SYS_STATS_RAM_GLOBAL5].used_cnt,
                               p_ram[SYS_STATS_RAM_GLOBAL6].used_cnt,
                               p_ram[SYS_STATS_RAM_GLOBAL7].used_cnt);

            for (j = SYS_STATS_TYPE_VLAN; j < SYS_STATS_TYPE_MAX; j++)
            {
                if (SYS_STATS_TYPE_SDC == j || SYS_STATS_TYPE_FID == j || SYS_STATS_TYPE_NSH == j)
                {
                    continue;
                }
                p_prop = &(usw_flow_stats_master[lchip]->stats_type[i][j]);

                SYS_STATS_DBG_DUMP(" %-17s%-10s", p_desc[j - SYS_STATS_TYPE_VLAN], "Ingress");

                for (r = SYS_STATS_RAM_GLOBAL0; r <= SYS_STATS_RAM_GLOBAL7; r++)
                {
                    if (!CTC_IS_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[r].stats_bmp[CTC_INGRESS], j))
                    {
                        SYS_STATS_DBG_DUMP("%-9s", "-");
                    }
                    else
                    {
                        SYS_STATS_DBG_DUMP("%-9u", p_prop->used_cnt_ram[r]);
                    }
                }

                //SYS_STATS_DBG_DUMP("%-12u", p_prop->used_cnt);

                SYS_STATS_DBG_DUMP("\n");
            }
        }
        else
        {
            for (j = SYS_STATS_TYPE_VLAN; j < SYS_STATS_TYPE_MAX; j++)
            {
                if ((SYS_STATS_TYPE_FIB == j)
                    || (SYS_STATS_TYPE_VRF == j)
                || (SYS_STATS_TYPE_QUEUE == j)
                || (SYS_STATS_TYPE_MAC == j)
                || (SYS_STATS_TYPE_FLOW_HASH == j)
                || (SYS_STATS_TYPE_ECMP == j)
                || (SYS_STATS_TYPE_HECMP == j)
                || (SYS_STATS_TYPE_SDC == j)
                || (SYS_STATS_TYPE_FID == j)
                || (SYS_STATS_TYPE_NSH == j))
                {
                    continue;
                }
                p_prop = &(usw_flow_stats_master[lchip]->stats_type[i][j]);

                SYS_STATS_DBG_DUMP(" %-17s%-10s", p_desc[j - SYS_STATS_TYPE_VLAN], "Egress");

                for (r = SYS_STATS_RAM_GLOBAL0; r <= SYS_STATS_RAM_GLOBAL7; r++)
                {
                    if (!CTC_IS_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[r].stats_bmp[CTC_EGRESS], j))
                    {
                        SYS_STATS_DBG_DUMP("%-9s", "-");
                    }
                    else
                    {
                        SYS_STATS_DBG_DUMP("%-9u", p_prop->used_cnt_ram[r]);
                    }
                }

                //SYS_STATS_DBG_DUMP("%-12u", p_prop->used_cnt);
                SYS_STATS_DBG_DUMP("\n");
            }

        }
        STATS_UNLOCK(lchip);
        SYS_STATS_DBG_DUMP(" ------------------------------------------------------------------------------------------------------------\n");

    }
    SYS_STATS_DBG_DUMP(" Ingress ACL private ram:\n");
    for(i=0; i <16; i++)
    {
        SYS_STATS_DBG_DUMP(" ACL%2u:%3u/%u%-5s",i,p_ram[SYS_STATS_RAM_IPE_ACL0+i].used_cnt, p_ram[SYS_STATS_RAM_IPE_ACL0+i].total_cnt,"");
        if (0 == ((i + 1) % 4))
        {
            SYS_STATS_DBG_DUMP("\n");
        }
    }
    SYS_STATS_DBG_DUMP("\n");
    SYS_STATS_DBG_DUMP(" Egress ACL private ram:\n");
    for(i=0; i <4; i++)
    {
        SYS_STATS_DBG_DUMP(" ACL%2u:%3u/%u%-5s",i,p_ram[SYS_STATS_RAM_EPE_ACL0+i].used_cnt, p_ram[SYS_STATS_RAM_EPE_ACL0+i].total_cnt,"");
    }
    SYS_STATS_DBG_DUMP("\n");
    return CTC_E_NONE;
}

#endif
#if defined(ARCTIC)
int32
_sys_at_flow_stats_type_init(uint8 lchip)
{
    uint8 ram = 0;
    uint8 dir = 2;
    uint8 priority = 0;
    sys_stats_prop_t* p_prop = NULL;

    /*SYS_STATS_TYPE_QUEUE*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_QUEUE]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_QUE_UC);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_QUE_UC].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_QUEUE);

    /*SYS_STATS_TYPE_QUEUE_MC*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_QUEUE_MC]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_QUE_MC);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_QUE_MC].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_QUEUE_MC);

    /*SYS_STATS_TYPE_DMA*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_DMA]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_DMA_UC);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_DMA_UC].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_DMA);

    /*SYS_STATS_TYPE_DMA_MC*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_DMA_MC]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_DMA_MC);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_DMA_MC].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_DMA_MC);

    /*SYS_STATS_TYPE_PORTTC*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_PORTTC]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_PORTTC_UC);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_PORTTC_UC].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_PORTTC);

    /*SYS_STATS_TYPE_PORTTC_MC*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_PORTTC_MC]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_PORTTC_MC);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_PORTTC_MC].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_PORTTC_MC);

    /*SYS_STATS_TYPE_VLAN*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_VLAN]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL5);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL5].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_VLAN);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_VLAN]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL14);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL14].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_VLAN);

    /*SYS_STATS_TYPE_INTF*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_INTF]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL6);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL6].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_INTF);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_INTF]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL13);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL13].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_INTF);

    /*SYS_STATS_TYPE_SCL*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_SCL]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL2);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL2].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_SCL);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_SCL]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL10);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL10].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_SCL);

    /*SYS_STATS_TYPE_TUNNEL*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_TUNNEL]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL3);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL3].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_TUNNEL);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_TUNNEL]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL11);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL11].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_TUNNEL);

    /*SYS_STATS_TYPE_LSP*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_LSP]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL5);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL5].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_LSP);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_LSP]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL11);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL11].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_LSP);

    /*SYS_STATS_TYPE_PW*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_PW]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL4);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL4].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_PW);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_PW]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL12);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL12].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_PW);

    /*SYS_STATS_TYPE_FWD_NH*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_FWD_NH]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL7);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL7].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_FWD_NH);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_FWD_NH]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL15);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL15].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_FWD_NH);

    /*SYS_STATS_TYPE_FIB*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_FIB]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL3);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL3].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_FIB);

    /*SYS_STATS_TYPE_FLOW_HASH*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_FLOW_HASH]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL4);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL4].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_FLOW_HASH);

    /*SYS_STATS_TYPE_MAC*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_MAC]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL7);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL7].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_MAC);


    /*SYS_STATS_TYPE_POLICER0*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_POLICER0]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL0);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL0].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_POLICER0);

    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_POLICER0]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL8);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL8].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_POLICER0);


    /*SYS_STATS_TYPE_POLICER1*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_POLICER1]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL1);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL1].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_POLICER1);
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_POLICER1]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL9);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL9].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_POLICER1);

     /*SYS_STATS_TYPE_NPM_IM*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_NPM_IM]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL4);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL4].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_NPM_IM);

    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_NPM_IM]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL11);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL11].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_NPM_IM);

    /*SYS_STATS_TYPE_NSH*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_NSH]);
    CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL12);
    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL12].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_NSH);

    /*SYS_STATS_TYPE_ACL*/
    for(ram = SYS_STATS_RAM_AT_EPE_ACL0; ram <= SYS_STATS_RAM_AT_IPE_ACL23; ram++)
    {
        dir = (ram < SYS_STATS_RAM_AT_IPE_ACL0) ? CTC_EGRESS : CTC_INGRESS;
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[dir][SYS_STATS_TYPE_ACL]);
        CTC_BMP_SET((uint32*)&p_prop->ram_bmp, ram);
        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[dir], SYS_STATS_TYPE_ACL);
        priority = (ram < SYS_STATS_RAM_AT_IPE_ACL0) ? (ram-SYS_STATS_RAM_AT_EPE_ACL0) : (ram-SYS_STATS_RAM_AT_IPE_ACL0);
        usw_flow_stats_master[lchip]->p_stats_ram[ram].acl_priority = priority;
    }

    if (SYS_STATS_TYPE_ENABLE(CTC_STATS_ECMP_STATS))
    {
        /*SYS_STATS_TYPE_ECMP*/
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_ECMP]);
        CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL4);
        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL4].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_ECMP);

        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_HECMP]);
        CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL7);
        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL7].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_HECMP);
    }

    if (SYS_STATS_TYPE_ENABLE(CTC_STATS_PORT_STATS))
    {
        /*SYS_STATS_TYPE_PORT*/
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_PORT]);
        CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL7);
        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL7].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_PORT);

        /*SYS_STATS_TYPE_PORT*/
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_PORT]);
        CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL11);
        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL11].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_PORT);
    }
    if (SYS_STATS_TYPE_ENABLE(CTC_STATS_FID_STATS))
    {
        /*SYS_STATS_TYPE_FID*/
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_FID]);
        CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL5);
        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL5].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_FID);

        /*SYS_STATS_TYPE_FID*/
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_FID]);
        CTC_BMP_SET((uint32*)&p_prop->ram_bmp, SYS_STATS_RAM_AT_GLOBAL14);
        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_AT_GLOBAL14].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_FID);
    }

    return CTC_E_NONE;
}

int32
sys_at_flow_stats_show_status(uint8 lchip)
{
    uint16 i = 0, j = 0, r = 0;
    char*  igr_desc[SYS_STATS_TYPE_MAX] = {"", "","", "","", "","Vlan", "L3if",  "Vrf", "Scl",   "TunnelDecap",  "MplsLspLabel",    "MplsVcLabel",   "Acl", "Forward", "Ip", "Policer0", "Policer1", "Ecmp", "Hecmp", "Port", "FlowHash", "Mac","","FID","","NPM-IM"};
    char*  egr_desc[SYS_STATS_TYPE_MAX] = {"",  "","", "","", "","Vlan", "L3if",  "Vrf", "Xlate", "TunnelEncap",  "NexthopMplsLsp",  "NexthopMplsPw", "Acl", "Nexthop", "",     "Policer0", "Policer1", "", "", "Port", "", "","Nsh", "FID","","NPM-IM"};
    char** p_desc = NULL;
    sys_stats_prop_t* p_prop = NULL;
    sys_stats_ram_prop_t* p_ram = NULL;
    LCHIP_CHECK(lchip);
    SYS_STATS_INIT_CHECK();
    p_ram = usw_flow_stats_master[lchip]->p_stats_ram;

    SYS_STATS_DBG_DUMP("\n");
    SYS_STATS_DBG_DUMP(" ------------------------------------------------------------------------------------------------------------\n");

    for (i = 0; i < CTC_BOTH_DIRECTION; i++)
    {
        p_desc = (CTC_INGRESS == i) ? igr_desc : egr_desc;
        STATS_LOCK(lchip);
        if(i == CTC_INGRESS)
        {
            SYS_STATS_DBG_DUMP(" %-17s%-10s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s\n",
                           "StatsType", "direction", "Global0", "Global1", "Global2", "Global3", "Global4", "Global5", "Global6", "Global7");
            SYS_STATS_DBG_DUMP(" %-27s%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u\n",
                               "pp ram:",
                               p_ram[SYS_STATS_RAM_AT_GLOBAL0].pp_en,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL1].pp_en,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL2].pp_en,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL3].pp_en,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL4].pp_en,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL5].pp_en,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL6].pp_en,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL7].pp_en);
            SYS_STATS_DBG_DUMP(" %-27s%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u\n",
                               "max cnt:",
                               p_ram[SYS_STATS_RAM_AT_GLOBAL0].total_cnt-1,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL1].total_cnt-1,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL2].total_cnt-1,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL3].total_cnt-1,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL4].total_cnt-1,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL5].total_cnt-1,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL6].total_cnt-1,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL7].total_cnt-1);
            SYS_STATS_DBG_DUMP(" %-27s%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u\n",
                               "used cnt:",
                               p_ram[SYS_STATS_RAM_AT_GLOBAL0].used_cnt,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL1].used_cnt,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL2].used_cnt,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL3].used_cnt,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL4].used_cnt,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL5].used_cnt,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL6].used_cnt,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL7].used_cnt);
            for (j = SYS_STATS_TYPE_VLAN; j < SYS_STATS_TYPE_MAX; j++)
            {
                if (SYS_STATS_TYPE_NSH == j || SYS_STATS_TYPE_SDC == j)
                {
                    continue;
                }
                p_prop = &(usw_flow_stats_master[lchip]->stats_type[i][j]);

                SYS_STATS_DBG_DUMP(" %-17s%-10s", p_desc[j], "Ingress");

                for (r = SYS_STATS_RAM_AT_GLOBAL0; r <= SYS_STATS_RAM_AT_GLOBAL7; r++)
                {
                    if (!CTC_IS_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[r].stats_bmp[CTC_INGRESS], j))
                    {
                        SYS_STATS_DBG_DUMP("%-9s", "-");
                    }
                    else
                    {
                        SYS_STATS_DBG_DUMP("%-9u", p_prop->used_cnt_ram[r]);
                    }
                }

                SYS_STATS_DBG_DUMP("\n");
            }
        }
        else
        {
            SYS_STATS_DBG_DUMP(" %-17s%-10s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s\n",
                           "StatsType", "direction", "Global8", "Global9", "Global10", "Global11", "Global12", "Global13", "Global14", "Global15");
            SYS_STATS_DBG_DUMP(" %-27s%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u\n",
                               "pp ram:",
                               p_ram[SYS_STATS_RAM_AT_GLOBAL8].pp_en,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL9].pp_en,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL10].pp_en,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL11].pp_en,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL12].pp_en,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL13].pp_en,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL14].pp_en,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL15].pp_en);
            SYS_STATS_DBG_DUMP(" %-27s%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u\n",
                               "max cnt:",
                               p_ram[SYS_STATS_RAM_AT_GLOBAL8].total_cnt-1,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL9].total_cnt-1,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL10].total_cnt-1,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL11].total_cnt-1,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL12].total_cnt-1,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL13].total_cnt-1,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL14].total_cnt-1,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL15].total_cnt-1);
            SYS_STATS_DBG_DUMP(" %-27s%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u\n",
                               "used cnt:",
                               p_ram[SYS_STATS_RAM_AT_GLOBAL8].used_cnt,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL9].used_cnt,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL10].used_cnt,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL11].used_cnt,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL12].used_cnt,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL13].used_cnt,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL14].used_cnt,
                               p_ram[SYS_STATS_RAM_AT_GLOBAL15].used_cnt);

            for (j = SYS_STATS_TYPE_VLAN; j < SYS_STATS_TYPE_MAX; j++)
            {
                if ((SYS_STATS_TYPE_FIB == j)
                    || (SYS_STATS_TYPE_VRF == j)
                || (SYS_STATS_TYPE_QUEUE == j)
                || (SYS_STATS_TYPE_QUEUE_MC== j)
                || (SYS_STATS_TYPE_MAC == j)
                || (SYS_STATS_TYPE_FLOW_HASH == j)
                || (SYS_STATS_TYPE_ECMP == j)
                || (SYS_STATS_TYPE_HECMP == j)
                || (SYS_STATS_TYPE_SDC == j))
                {
                    continue;
                }
                p_prop = &(usw_flow_stats_master[lchip]->stats_type[i][j]);

                SYS_STATS_DBG_DUMP(" %-17s%-10s", p_desc[j], "Egress");

                for (r = SYS_STATS_RAM_AT_GLOBAL8; r <= SYS_STATS_RAM_AT_GLOBAL15; r++)
                {
                    if (!CTC_IS_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[r].stats_bmp[CTC_EGRESS], j))
                    {
                        SYS_STATS_DBG_DUMP("%-9s", "-");
                    }
                    else
                    {
                        SYS_STATS_DBG_DUMP("%-9u", p_prop->used_cnt_ram[r]);
                    }
                }

                //SYS_STATS_DBG_DUMP("%-12u", p_prop->used_cnt);
                SYS_STATS_DBG_DUMP("\n");
            }

        }
        STATS_UNLOCK(lchip);
        SYS_STATS_DBG_DUMP(" ------------------------------------------------------------------------------------------------------------\n");

    }

    SYS_STATS_DBG_DUMP(" Ingress ACL private ram:(used/total/pp_en)\n");
    for(i=0; i <MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM); i++)
    {
        SYS_STATS_DBG_DUMP(" ACL%2u:%3u/%u/%u%-5s",i,p_ram[SYS_STATS_RAM_AT_IPE_ACL0+i].used_cnt, p_ram[SYS_STATS_RAM_AT_IPE_ACL0+i].total_cnt,p_ram[SYS_STATS_RAM_AT_IPE_ACL0+i].pp_en,"");
        if (0 == ((i + 1) % 4))
        {
            SYS_STATS_DBG_DUMP("\n");
        }
    }
    SYS_STATS_DBG_DUMP("\n");
    SYS_STATS_DBG_DUMP(" Egress ACL private ram:(used/total/pp_en)\n");
    for(i=0; i <MCHIP_CAP(SYS_CAP_ACL_EGRESS_LKUP_NUM); i++)
    {
        SYS_STATS_DBG_DUMP(" ACL%2u:%3u/%u/%u%-5s",i,p_ram[SYS_STATS_RAM_AT_EPE_ACL0+i].used_cnt, p_ram[SYS_STATS_RAM_AT_EPE_ACL0+i].total_cnt, p_ram[SYS_STATS_RAM_AT_EPE_ACL0+i].pp_en,"");
        if (0 == ((i + 1) % 4))
        {
            SYS_STATS_DBG_DUMP("\n");
        }
    }
    SYS_STATS_DBG_DUMP("\n");
    return CTC_E_NONE;
}

#endif
STATIC int32
_sys_usw_flow_stats_free_node(void* node_data, void* user_data)
{
    mem_free(node_data);

    return CTC_E_NONE;
}

uint8 _sys_usw_flow_stats_acl_bit2ram(uint8 lchip, uint8 bit_offset, uint8 dir)
{
    uint8 ram = 0xff;
    uint8 ram_base[CTC_BOTH_DIRECTION] = {0};

    if(DRV_FROM_TMM(lchip))
    {
        ram_base[CTC_INGRESS] = DRV_FROM_AT(lchip) ? SYS_STATS_RAM_AT_IPE_ACL0 : SYS_STATS_RAM_IPE_ACL0;
        ram_base[CTC_EGRESS] = DRV_FROM_AT(lchip) ? SYS_STATS_RAM_AT_EPE_ACL0 : SYS_STATS_RAM_EPE_ACL0;
        if(dir == CTC_INGRESS)
        {
            if(bit_offset < MCHIP_CAP(SYS_CAP_STATS_PRIVATE_IPE_RAM_NUM))
            {
                ram = ram_base[dir] + bit_offset;
            }
        }
        else
        {
            if(bit_offset < MCHIP_CAP(SYS_CAP_STATS_PRIVATE_EPE_RAM_NUM))
            {
                ram = ram_base[dir] + bit_offset;
            }
        }
    }
    else
    {
        if(dir == CTC_INGRESS)
        {
            if(bit_offset < MCHIP_CAP(SYS_CAP_STATS_GLOBAL_RAM_NUM))
            {
                ram = SYS_STATS_RAM_IPE_GLOBAL0 + bit_offset;
            }
            else if(bit_offset < (MCHIP_CAP(SYS_CAP_STATS_GLOBAL_RAM_NUM) + MCHIP_CAP(SYS_CAP_STATS_PRIVATE_IPE_RAM_NUM)))
            {
                ram = SYS_STATS_RAM_IPE_PRIVATE0 + (bit_offset - MCHIP_CAP(SYS_CAP_STATS_GLOBAL_RAM_NUM));
            }
        }
        else
        {
            if(bit_offset < MCHIP_CAP(SYS_CAP_STATS_GLOBAL_RAM_NUM))
            {
                ram = SYS_STATS_RAM_EPE_GLOBAL0 + bit_offset;
            }
            else if(bit_offset < (MCHIP_CAP(SYS_CAP_STATS_GLOBAL_RAM_NUM)+MCHIP_CAP(SYS_CAP_STATS_PRIVATE_EPE_RAM_NUM)))
            {
                ram = SYS_STATS_RAM_EPE_PRIVATE0 + (bit_offset - MCHIP_CAP(SYS_CAP_STATS_GLOBAL_RAM_NUM));
            }
        }
    }
    return ram;
}


#define __9_STATS_API__

int32
sys_usw_flow_stats_update_ecmp_stats(uint8 lchip, uint32 new_num, uint32 old_num, uint8 hecmp_en)
{
    sys_stats_prop_t* p_prop = NULL;
    int32 ret = CTC_E_NONE;
    uint16 entry_num = new_num >> hecmp_en;
    uint8 i = 0;

    hecmp_en = DRV_FROM_AT(lchip) ? hecmp_en : 0;

    STATS_LOCK(lchip);

    /* 1. check if ecmp stats_id used */
    i = hecmp_en;
    do
    {
        entry_num = i ? entry_num : entry_num + hecmp_en;
        p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_ECMP + i]);
        if(p_prop->used_cnt > entry_num)
        {
            ret = CTC_E_IN_USE;
            goto done;
        }
    }while(i--);
    
    /* 2. free old ecmp stats ptr */
    _sys_usw_flow_stats_free_ecmp_stats(lchip, old_num, hecmp_en);
    
    /* 3. alloc new ecmp stats ptr */
    CTC_ERROR_GOTO(_sys_usw_flow_stats_alloc_ecmp_stats(lchip, new_num, hecmp_en), ret, error1);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_MASTER, 1);

    usw_flow_stats_master[lchip]->max_ecmp_num = new_num;
    usw_flow_stats_master[lchip]->hecmp_en = hecmp_en;
    goto done;

error1: /* roll back old stats ptr*/
    _sys_usw_flow_stats_free_ecmp_stats(lchip, new_num, hecmp_en);
    _sys_usw_flow_stats_alloc_ecmp_stats(lchip, old_num, hecmp_en);
done: /* unlock */
    STATS_UNLOCK(lchip);
    return ret;
}


int32
sys_usw_flow_stats_sync_fifo_stats(uint8 lchip, uint32 intr, void* p_data)
{
    sys_intr_type_t type;
    switch (intr)
    {
        case SYS_INTR_FUNC_STATS_STATUS_ADDR_SLICE_1:
            lchip += 1;
            break;
        case SYS_INTR_FUNC_STATS_STATUS_ADDR_SLICE_2:
            lchip += 2;
            break;
        case SYS_INTR_FUNC_STATS_STATUS_ADDR_SLICE_3:
            lchip += 3;
            break;
        default:
            break;
    }
    sal_memset(&type, 0, sizeof(type));
    type.intr = intr;
    type.sub_intr = INVG;
    sys_usw_interrupt_set_en(lchip, &type, FALSE);
    if (MCHIP_F_STATS(lchip)->sync_fifo_stats)
    {
        STATS_LOCK(lchip);
        MCHIP_F_STATS(lchip)->sync_fifo_stats(lchip);
        STATS_UNLOCK(lchip);
    }
    sys_usw_interrupt_set_en(lchip, &type, TRUE);
    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_get_mem_usage(uint8 lchip, ctc_stats_mem_usage_t* p_status)
{
    sys_stats_ram_prop_t* p_ram = NULL;
    uint8 ram = 0;
    uint8 ram_max = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);
    uint8 sys_type = 0;
    uint8 sys_dir = 0;
    uint8 rsv_cnt = 0;
    uint32 lkup_bmp = 0;

    /* check param */
    SYS_STATS_INIT_CHECK();
    CTC_MAX_VALUE_CHECK(p_status->dir, CTC_BOTH_DIRECTION-1);
    p_status->total_size = 0;
    p_status->used_cnt = 0;

    /* only tmm acl and queue stats can use stats-ptr 0 */
    rsv_cnt = (DRV_FROM_TMM(lchip) && ((p_status->type == CTC_STATS_STATSID_TYPE_ACL) \
               || (CTC_STATS_STATSID_TYPE_ACL2 == p_status->type))) ? 0 : 1;
    if((p_status->type == CTC_STATS_STATSID_TYPE_ACL) || (CTC_STATS_STATSID_TYPE_ACL2 == p_status->type))
    {
        CTC_MAX_VALUE_CHECK(p_status->acl_priority, (CTC_INGRESS == p_status->dir)? (MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM)-1) : (MCHIP_CAP(SYS_CAP_ACL_EGRESS_LKUP_NUM)-1));
        lkup_bmp = sys_usw_acl_get_lkup_level_bmp(lchip, p_status->dir, p_status->acl_priority);
    }

    CTC_ERROR_RETURN(_sys_usw_flow_stats_map_type(lchip, p_status->type, 0, &sys_type, &sys_dir));
    sys_dir = sys_dir == CTC_BOTH_DIRECTION ? p_status->dir : sys_dir;
    STATS_LOCK(lchip);
    for(ram = 0; ram < ram_max; ram++)
    {
        p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[ram]);
        if(!CTC_IS_BIT_SET(p_ram->stats_bmp[sys_dir], sys_type))
        {
            continue;
        }
        if(sys_type == SYS_STATS_TYPE_ACL && !CTC_IS_BIT_SET(lkup_bmp, p_ram->acl_priority))
        {
            continue;
        }

        p_status->total_size += p_ram->total_cnt - rsv_cnt;
        p_status->used_cnt += p_ram->used_cnt;
    }
    STATS_UNLOCK(lchip);
    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_ram_assign(uint8 lchip, uint16 ram_bmp[][CTC_BOTH_DIRECTION], uint32 acl_ram_bmp[][CTC_BOTH_DIRECTION], uint32 scl_ram_bmp[][CTC_BOTH_DIRECTION])
{
    int32 ret = 0;
    uint8 dir = 0;
    uint8 ctc_type = 0;
    uint8 acl_pri = 0;
    uint8 scl_pri = 0;
    uint8 i = 0, ram = 0;
    sys_stats_prop_t* p_prop = NULL;
    uint8 sys_type = 0;
    uint8 ram_id[CTC_BOTH_DIRECTION] = {0};
    uint8 flag[CTC_BOTH_DIRECTION] = {0};
    uint32 stats_entry_cnt = 0;
    uint32 stats_id_cnt = 0;
    uint8 bit_cnt[SYS_ACL_RAM_NUM] = {0};
    uint8 glb_ram = MCHIP_CAP(SYS_CAP_STATS_GLOBAL_RAM_NUM);
    uint8 ram_num = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);
    uint8 acl_num = 0;
    uint8 scl_num = 0;
    uint8 scl_egs_num = 2;
    int32 scl_ram_bmp_cnt = 0;
    uint32 sys_ram_bmp[CTC_BOTH_DIRECTION] = {0};
    uint8 base_glb_igs_ram = DRV_FROM_AT(lchip) ? SYS_STATS_RAM_AT_GLOBAL0:(DRV_IS_TMM(lchip)? SYS_STATS_RAM_GLOBAL0:SYS_STATS_RAM_IPE_GLOBAL0);
    uint8 base_glb_egs_ram = DRV_FROM_AT(lchip) ? SYS_STATS_RAM_AT_GLOBAL0:(DRV_IS_TMM(lchip)? SYS_STATS_RAM_GLOBAL0:SYS_STATS_RAM_EPE_GLOBAL0);
    
    SYS_STATS_INIT_CHECK();
    CTC_BMP_COUNT_RANGE(&scl_ram_bmp[0][0], scl_ram_bmp_cnt, 0, CTC_CONST32*CTC_MAX_SCL_LKUP_NUM*CTC_BOTH_DIRECTION);
    /* check scl_ram_bmp */
    for(i = 0;i < CTC_MAX_SCL_LKUP_NUM; i++)
    {
        if(i >= scl_egs_num && scl_ram_bmp[i][CTC_EGRESS])
        {
            SYS_STATS_DBG_ERROR("egress scl priority %d is invalid!\n", i);
            return CTC_E_INTR_INVALID_PARAM;
        }
        sys_ram_bmp[CTC_INGRESS] |= scl_ram_bmp[i][CTC_INGRESS];
        sys_ram_bmp[CTC_EGRESS] |= scl_ram_bmp[i][CTC_EGRESS];
    }

    if (DRV_FROM_TMM(lchip))
    {
        for (ctc_type = 0; ctc_type < CTC_STATS_STATSID_TYPE_MAX; ctc_type++)
        {
            if(scl_ram_bmp_cnt && CTC_STATS_STATSID_TYPE_SCL == ctc_type)
            {
                continue;
            }
            sys_ram_bmp[CTC_INGRESS] |= ram_bmp[ctc_type][CTC_INGRESS];
            sys_ram_bmp[CTC_EGRESS] |= ram_bmp[ctc_type][CTC_EGRESS];
        }
        if(sys_ram_bmp[CTC_INGRESS] & sys_ram_bmp[CTC_EGRESS])
        {
            SYS_STATS_DBG_ERROR("one ram, it's can only use for ingress or egress\n");
            return CTC_E_INTR_INVALID_PARAM;
        }
        if(DRV_FROM_AT(lchip) && (sys_ram_bmp[CTC_EGRESS]&0x00FF || sys_ram_bmp[CTC_INGRESS]&0xFF00))
        {
            SYS_STATS_DBG_ERROR("stats type, 0~7 bitmp ingress,8-15 bitmp egress\n");
            return CTC_E_INTR_INVALID_PARAM;
        }
    }

    if (ram_bmp[CTC_STATS_STATSID_TYPE_NSH][CTC_INGRESS])
    {
        SYS_STATS_DBG_ERROR("nsh only support egress\n");
        return CTC_E_INTR_INVALID_PARAM;
    }

    for(i = 0; i < 16; i++)
    {
        if(CTC_IS_BIT_SET(ram_bmp[CTC_STATS_STATSID_TYPE_ECMP][CTC_INGRESS],i))
        {
            if (!SYS_STATS_TYPE_ENABLE(CTC_STATS_ECMP_STATS))
            {
                SYS_STATS_DBG_ERROR("ecmp stats not enable!\n");
                return CTC_E_NOT_SUPPORT;
            }
            bit_cnt[0]++;
        }
        if(CTC_IS_BIT_SET(ram_bmp[CTC_STATS_STATSID_TYPE_PORT][CTC_INGRESS],i))
        {
            if (!SYS_STATS_TYPE_ENABLE(CTC_STATS_PORT_STATS))
            {
                SYS_STATS_DBG_ERROR("port stats not enable!\n");
                return CTC_E_NOT_SUPPORT;
            }
            bit_cnt[1]++;
        }
        if(CTC_IS_BIT_SET(ram_bmp[CTC_STATS_STATSID_TYPE_PORT][CTC_EGRESS],i))
        {
            if (!SYS_STATS_TYPE_ENABLE(CTC_STATS_PORT_STATS))
            {
                SYS_STATS_DBG_ERROR("port stats not enable!\n");
                return CTC_E_NOT_SUPPORT;
            }
            bit_cnt[2]++;
        }
        if (CTC_IS_BIT_SET(ram_bmp[CTC_STATS_STATSID_TYPE_NSH][CTC_EGRESS], i))
        {
            bit_cnt[3]++;
        }
        if (CTC_IS_BIT_SET(ram_bmp[CTC_STATS_STATSID_TYPE_FID][CTC_INGRESS], i))
        {
            if (!SYS_STATS_TYPE_ENABLE(CTC_STATS_FID_STATS))
            {
                SYS_STATS_DBG_ERROR("fid stats not enable!\n");
                return CTC_E_NOT_SUPPORT;
            }
            ram_id[CTC_INGRESS] += flag[CTC_INGRESS]? 1: i;
            flag[CTC_INGRESS] = 1;
            if (ram_id[CTC_INGRESS] != i)
            {
                SYS_STATS_DBG_ERROR("fid stats must use successive ram id\n");
                return CTC_E_NOT_SUPPORT;
            }
        }
        if (CTC_IS_BIT_SET(ram_bmp[CTC_STATS_STATSID_TYPE_FID][CTC_EGRESS], i))
        {
            if (!SYS_STATS_TYPE_ENABLE(CTC_STATS_FID_STATS))
            {
                SYS_STATS_DBG_ERROR("fid stats not enable!\n");
                return CTC_E_NOT_SUPPORT;
            }
            ram_id[CTC_EGRESS] += flag[CTC_EGRESS]? 1: i;
            flag[CTC_EGRESS] = 1;
            if (ram_id[CTC_EGRESS] != i)
            {
                SYS_STATS_DBG_ERROR("fid stats must use successive ram id\n");
                return CTC_E_NOT_SUPPORT;
            }
        }
    }
    if(bit_cnt[0] > 1 || bit_cnt[1] > 1 || bit_cnt[2] > 1 || bit_cnt[3] > 1)
    {
        SYS_STATS_DBG_ERROR("nsh & ecmp & port stats only one bit can be set\n");
        return CTC_E_INTR_INVALID_PARAM;
    }

    STATS_LOCK(lchip);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_MASTER, 1);
    ctc_hash_get_count(usw_flow_stats_master[lchip]->flow_stats_id_hash, &stats_id_cnt);
    //ctc_vector_get_count(usw_flow_stats_master[lchip]->flow_stats_hash, &stats_entry_cnt);
    stats_entry_cnt = _sys_usw_flow_stats_vec_cnt(lchip);
    if( stats_entry_cnt > usw_flow_stats_master[lchip]->init_entry_cnt || stats_id_cnt)
    {
        SYS_STATS_DBG_ERROR("must be configed before creat first stats_id\n");
        STATS_UNLOCK(lchip);
        return CTC_E_IN_USE;
    }

    for(dir = 0; dir < CTC_BOTH_DIRECTION; dir++)
    {
        sal_memset(bit_cnt, 0, sizeof(bit_cnt));
        for (acl_pri = 0; acl_pri < CTC_MAX_ACL_LKUP_NUM; acl_pri++)
        {
            for (ram = 0; ram < SYS_ACL_RAM_NUM; ram++)
            {
                if (CTC_IS_BIT_SET(acl_ram_bmp[acl_pri][dir], ram))
                {
                    bit_cnt[ram]++;
                }
                if (bit_cnt[ram] > 1)
                {
                    STATS_UNLOCK(lchip);
                    return CTC_E_INTR_INVALID_PARAM;
                }
            }
        }
    }

    CTC_ERROR_GOTO(_sys_usw_flow_stats_free_solid_type(lchip), ret, error_roll);

    for (ctc_type = 0; ctc_type < CTC_STATS_STATSID_TYPE_MAX; ctc_type++)
    {
        if(((CTC_STATS_STATSID_TYPE_FID == ctc_type || CTC_STATS_STATSID_TYPE_HECMP == ctc_type) && !DRV_FROM_AT(lchip))
        || CTC_STATS_STATSID_TYPE_SDC == ctc_type || CTC_STATS_STATSID_TYPE_ACL == ctc_type || CTC_STATS_STATSID_TYPE_ACL2 == ctc_type)
        {
            continue;
        }
        if (SYS_TMM_STATS_TYPE_VRF(lchip, ctc_type))
        {
            continue;
        }

        CTC_ERROR_DUMP(_sys_usw_flow_stats_map_type(lchip, ctc_type, 0, &sys_type, &dir));

        if(CTC_BOTH_DIRECTION == dir || CTC_INGRESS == dir)
        {
            p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][sys_type]);
            p_prop->pp_en = 0;
            for (i = 0; i < glb_ram; i++)/*only set global ram*/
            {
                ram = base_glb_igs_ram + i;
                usw_flow_stats_master[lchip]->p_stats_ram[ram].scl_bmp = 0;
                if (scl_ram_bmp_cnt && CTC_STATS_STATSID_TYPE_SCL == ctc_type)
                {
                    CTC_BIT64_UNSET(p_prop->ram_bmp, ram);
                    CTC_BIT_UNSET(usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[CTC_INGRESS], sys_type);
                    continue;
                }
                if (CTC_IS_BIT_SET(ram_bmp[ctc_type][CTC_INGRESS], i))
                {
                    CTC_BIT64_SET(p_prop->ram_bmp, ram);
                    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[CTC_INGRESS], sys_type);
                }
                else
                {
                    CTC_BIT64_UNSET(p_prop->ram_bmp, ram);
                    CTC_BIT_UNSET(usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[CTC_INGRESS], sys_type);
                }
            }
        }

        if(CTC_BOTH_DIRECTION == dir || CTC_EGRESS == dir)
        {
            p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][sys_type]);
            for (i = 0; i < glb_ram; i++)/*only set global ram*/
            {
                ram = base_glb_egs_ram + i;
                usw_flow_stats_master[lchip]->p_stats_ram[ram].scl_bmp = 0;
                if (scl_ram_bmp_cnt && CTC_STATS_STATSID_TYPE_SCL == ctc_type)
                {
                    CTC_BIT64_UNSET(p_prop->ram_bmp, ram);
                    CTC_BIT_UNSET(usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[CTC_EGRESS], sys_type);
                    continue;
                }
                if (CTC_IS_BIT_SET(ram_bmp[ctc_type][CTC_EGRESS], i))
                {
                    CTC_BIT64_SET(p_prop->ram_bmp, ram);
                    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[CTC_EGRESS], sys_type);
                }
                else
                {
                    CTC_BIT64_UNSET(p_prop->ram_bmp, ram);
                    CTC_BIT_UNSET(usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[CTC_EGRESS], sys_type);
                }
            }
        }
    }

    usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_ACL].ram_bmp = 0;
    usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_ACL].pp_en = 0;
    usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_ACL].ram_bmp = 0;
    usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][SYS_STATS_TYPE_ACL].pp_en = 0;
    for(ram = 0; ram < ram_num; ram++)
    {
        CTC_BIT_UNSET(usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_ACL);
        CTC_BIT_UNSET(usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[CTC_EGRESS], SYS_STATS_TYPE_ACL);
    }


    for(dir = 0; dir < CTC_BOTH_DIRECTION; dir++)
    {
        acl_num = (dir == CTC_INGRESS) ? MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM) : MCHIP_CAP(SYS_CAP_ACL_EGRESS_LKUP_NUM);
        for (acl_pri = 0; acl_pri < acl_num; acl_pri++)
        {
            for (i = 0; i < 32; i++)/*bitmap*/
            {
                if (CTC_IS_BIT_SET(acl_ram_bmp[acl_pri][dir], i))
                {
                    ram = _sys_usw_flow_stats_acl_bit2ram(lchip, i, dir);
                    if(ram == 0xFF)
                    {
                        break;
                    }
                    CTC_BIT64_SET(usw_flow_stats_master[lchip]->stats_type[dir][SYS_STATS_TYPE_ACL].ram_bmp, ram);
                    CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[dir], SYS_STATS_TYPE_ACL);
                    usw_flow_stats_master[lchip]->p_stats_ram[ram].acl_priority = acl_pri;
                }
            }
        }
        scl_num = (dir == CTC_INGRESS) ? 4 : 2;
        if(scl_ram_bmp_cnt)
        {
            usw_flow_stats_master[lchip]->stats_type[dir][SYS_STATS_TYPE_SCL].ram_bmp = 0;
            usw_flow_stats_master[lchip]->stats_type[dir][SYS_STATS_TYPE_SCL].pp_en = 0;
            
            for (scl_pri = 0; scl_pri < scl_num; scl_pri++)
            {
                for (i = 0; i < MCHIP_CAP(SYS_CAP_STATS_GLOBAL_RAM_NUM); i++)/*bitmap*/
                {
                    if (CTC_IS_BIT_SET(scl_ram_bmp[scl_pri][dir], i))
                    {
                        ram = ((dir == CTC_INGRESS)? base_glb_igs_ram: base_glb_egs_ram) + i;
                        CTC_BIT64_SET(usw_flow_stats_master[lchip]->stats_type[dir][SYS_STATS_TYPE_SCL].ram_bmp, ram);
                        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[ram].stats_bmp[dir], SYS_STATS_TYPE_SCL);
                        CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[ram].scl_bmp, scl_pri);
                    }
                }
            }
        }
    }

    CTC_ERROR_GOTO(_sys_usw_flow_stats_alloc_solid_type(lchip), ret, error_roll);
    CTC_ERROR_GOTO(_sys_usw_flow_stats_alloc_fid_type(lchip), ret, error_roll);
    CTC_ERROR_GOTO(_sys_usw_flow_stats_global_ram_en(lchip), ret, error_roll);
    if(DRV_FROM_AT(lchip))
    {
        _sys_usw_flow_stats_determine_pp_ram(lchip);
    }

    STATS_UNLOCK(lchip);

    return CTC_E_NONE;

error_roll:
    STATS_UNLOCK(lchip);
    return ret;
}

/* get stats property by stats id*/
int32
sys_usw_flow_stats_get_statsid(uint8 lchip, sys_stats_statsid_t* p_statsid)
{
    sys_stats_statsid_t* p_statsid_rse = NULL;
    uint8 size = 0;
    uint8 pp_base = SYS_PP_BASE(lchip);

    SYS_STATS_DBG_FUNC();
    SYS_STATS_INIT_CHECK();

    SYS_MAP_LCHIP_WITH_LOCK(lchip, pp_base, p_statsid->stats_id_type, p_statsid->dir)
    p_statsid_rse = ctc_hash_lookup(usw_flow_stats_master[lchip]->flow_stats_id_hash, p_statsid);
    if (p_statsid_rse == NULL)
    {
        SYS_STATS_DBG_ERROR(" Entry not exist \n");
        STATS_UNLOCK(lchip);
        return CTC_E_NOT_EXIST;
    }
    size = (SYS_STATS_TYPE_ACL == p_statsid_rse->stats_id_type) ? sizeof(sys_stats_statsid_acl_t):
          ((SYS_STATS_TYPE_NPM_IM == p_statsid_rse->stats_id_type) ? sizeof(sys_stats_statsid_npm_im_t): sizeof(sys_stats_statsid_t));
    sal_memcpy(p_statsid, p_statsid_rse, size);
    STATS_UNLOCK(lchip);

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_flow_stats_get_statsptr(uint8 lchip, uint32 stats_id, uint32* p_cache_ptr)
{
    sys_stats_statsid_t statsid_lkp;
    sys_stats_statsid_t* p_statsid_res = NULL;
    sys_stats_param_t st_parm;
    uint32 field_val = 0;
    uint8 ram = 0;
    int32 ret = CTC_E_NONE;
    uint32 cmd =0;

    SYS_STATS_DBG_FUNC();
    SYS_STATS_INIT_CHECK();
    CTC_PTR_VALID_CHECK(p_cache_ptr);

    sal_memset(&statsid_lkp, 0, sizeof(statsid_lkp));
    sal_memset(&st_parm, 0, sizeof(st_parm));
    statsid_lkp.stats_id = stats_id;
    p_statsid_res = ctc_hash_lookup(usw_flow_stats_master[lchip]->flow_stats_id_hash, &statsid_lkp);
    if (p_statsid_res == NULL)
    {
        SYS_STATS_DBG_ERROR(" Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    if (SYS_STATS_TYPE_NSH == p_statsid_res->stats_id_type
        && (usw_flow_stats_master[lchip]->stats_type[CTC_EGRESS][p_statsid_res->stats_id_type].used_cnt >= SYS_AT_NSH_STATS_NUM))
    {
        SYS_STATS_DBG_ERROR(" NSH Stats no resource!!! \n");
        CTC_ERROR_RETURN(CTC_E_NO_RESOURCE);
    }

    if (!p_statsid_res->stats_ptr_valid)
    {
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_STATSID, 1);
        st_parm.dir = p_statsid_res->dir;
        st_parm.type = p_statsid_res->stats_id_type;
        st_parm.num = 1;
        CTC_ERROR_RETURN(_sys_usw_flow_stats_alloc_statsptr(lchip, &st_parm));
        p_statsid_res->stats_ptr = st_parm.ptr;
        ret = _sys_usw_flow_stats_entry_create(lchip, st_parm.num, p_statsid_res->stats_id, p_statsid_res->stats_ptr);
        if (ret != CTC_E_NONE)
        {
            _sys_usw_flow_stats_free_statsptr(lchip, &st_parm);
            CTC_ERROR_RETURN(ret);
        }
        _sys_usw_flow_stats_clear_stats(lchip, st_parm.num, p_statsid_res->stats_ptr);
        p_statsid_res->stats_ptr_valid = 1;
    }

    ram = SYS_STATS_DECODE_PTR_RAM(p_statsid_res->stats_ptr);
    *p_cache_ptr = _sys_usw_flow_stats_encode_hw_ptr(lchip, ram, SYS_STATS_DECODE_PTR_OFFSET(p_statsid_res->stats_ptr));

    if(p_statsid_res->stats_id_type == SYS_STATS_TYPE_FLOW_HASH )
    {
        cmd = DRV_IOR(IpeFlowHashCtl_t, IpeFlowHashCtl_igrIpfix32KMode_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
        if(!field_val)
        {
            return ret;
        }
        *p_cache_ptr = (uint32)SYS_STATS_ENCODE_CHIP_32K_PTR(ram, SYS_STATS_DECODE_PTR_OFFSET(p_statsid_res->stats_ptr));
        if(ram >= SYS_STATS_RAM_EPE_GLOBAL0 && ram <=SYS_STATS_RAM_EPE_GLOBAL3)
        {
            *p_cache_ptr |= (1<<14);
        }
    }

    SYS_STATS_DBG_INFO("stats_id:%u, stats_ptr:0x%08X, cache_ptr:0x%04X\n", stats_id, p_statsid_res->stats_ptr, *p_cache_ptr);

    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_get_statsptr(uint8 lchip, uint32 stats_id, uint32* p_cache_ptr)
{
    int32 ret = CTC_E_NONE;
    uint8 pp_en = 0;
    uint8 pp_base = SYS_PP_BASE(lchip);

    if (lchip != pp_base)
    {
        CTC_ERROR_RETURN(sys_usw_flow_stats_get_stats_type_pp_en_by_stats_id(pp_base, stats_id, &pp_en));
        if (!pp_en)
        {
            lchip = pp_base;
        }
    }

    STATS_LOCK(lchip);
    ret = _sys_usw_flow_stats_get_statsptr(lchip, stats_id, p_cache_ptr);
    STATS_UNLOCK(lchip);

    return ret;
}

int32
sys_tmm_flow_stats_get_acl_stats_ram_id(uint8 lchip, uint32 stats_ptr, uint8 dir, uint8* hw_ram_idx, uint32* P_cache_ptr)
{
    uint8 ram = 0;

    ram = SYS_STATS_DECODE_PTR_RAM(stats_ptr);
    if(DRV_FROM_AT(lchip))
    {
        if(ram <= SYS_STATS_RAM_AT_EPE_ACL11)
        {
            *hw_ram_idx = ram - SYS_STATS_RAM_AT_EPE_ACL0;
        }
        else if(SYS_STATS_RAM_AT_IPE_ACL0 <= ram &&  ram <= SYS_STATS_RAM_AT_IPE_ACL23)
        {
            *hw_ram_idx = ram - SYS_STATS_RAM_AT_IPE_ACL0;
        }
        else
        {
            if(dir == CTC_INGRESS)
            {
                *hw_ram_idx = ram - SYS_STATS_RAM_AT_GLOBAL0 + 24;
            }
            else
            {
                *hw_ram_idx = ram - SYS_STATS_RAM_AT_GLOBAL8 + 12;
            }
        }
    }
    else
    {
        if (ram <= SYS_STATS_RAM_EPE_ACL3)
        {
            *hw_ram_idx = ram - SYS_STATS_RAM_EPE_ACL0;
        }
        else if (ram <= SYS_STATS_RAM_IPE_ACL15)
        {
            *hw_ram_idx = ram - SYS_STATS_RAM_IPE_ACL0;
        }
        else
        {
            if (dir == CTC_INGRESS)
            {
                *hw_ram_idx = ram - SYS_STATS_RAM_GLOBAL0 + 16;
            }
            else
            {
                *hw_ram_idx = ram - SYS_STATS_RAM_GLOBAL0 + 4;
            }
        }
        }
    *P_cache_ptr = _sys_usw_flow_stats_encode_hw_ptr(lchip, ram, SYS_STATS_DECODE_PTR_OFFSET(stats_ptr));

    return CTC_E_NONE;
}

int32
_sys_usw_flow_stats_read_buf_count(uint8 lchip, uint16 offset, uint8 ram, ctc_stats_basic_t* p_cnt)
{
    uint32 cmd = 0;
    uint32 cmd2 = 0;
    DsStats_m   ds;
    uint32 buf_ds = 0;
    uint32 buf_ds2 = 0;
    uint32 hw_stats_idx = 0;
    uint32 tbl_id = 0;
    ctc_stats_basic_t count;

    hw_stats_idx = usw_flow_stats_master[lchip]->p_stats_ram[ram].base_idx + offset;
    sal_memset(&count, 0, sizeof(ctc_stats_basic_t));

    cmd = DRV_IOR(DsStats_t, DRV_ENTRY_FLAG);
    /* for cache hw, cpu read do not clear, but Chip read clear */
    drv_usw_ftm_get_flow_stats_table_id(lchip, ram, &tbl_id);
    cmd2 = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, offset, DRV_CMD_PP_EN(cmd2), &buf_ds));
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, hw_stats_idx, DRV_CMD_PP_EN(cmd), &ds));

    CTC_ERROR_RETURN(DRV_IOCTL(lchip, offset, DRV_CMD_PP_EN(cmd2), &buf_ds2));
    if(buf_ds && buf_ds2==0)
    {
        /* means cache data had move to DsStats, need read DsStats again */
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, hw_stats_idx, DRV_CMD_PP_EN(cmd), &ds));
    }
    MCHIP_F_STATS(lchip)->ds2count(lchip, DsStats_t, &ds, &count);
    /* cache stats: bit 0-15 byte_cnt, bit 16-23 packet_cnt */
    p_cnt->byte_count += count.byte_count + (buf_ds & 0xffff);
    p_cnt->packet_count += count.packet_count + ((buf_ds >> 16) & 0xff);

    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_change_acl_statsptr(uint8 lchip, sys_stats_acl_change_t* p_acl_change)
{
    int32 ret = CTC_E_NONE;
    sys_stats_statsid_t statsid;
    sys_stats_statsid_t* p_statsid_res = NULL;
    sys_stats_statsid_acl_t* p_statsid_acl = NULL;
    sys_stats_param_t sts_param;
    uint32 old_stats_ptr;
    uint16 stats_offset = 0;
    uint16 ram_offset = 0;
    uint8  ram;
    uint8  loop = 0;
    uint8  loop2;
    uint8  blk_id = 0;
    uint32 tmp_stats_ptr;
    uint32 tbl_id;
    DsStats_m* hw_stats;
    ctc_stats_basic_t dma_count;
    ctc_stats_basic_t count[3];
    uint32*           dma_data[SYS_DMA_FLOW_STATS_DESC_DEPTH*8];
    uint8 data_base = 0;
    sys_stats_flow_stats_t* p_flow_stats = NULL;
    uint8 pp_base = SYS_PP_BASE(lchip);
    uint8 pp_num = SYS_PP_BMP(lchip);
    uint8 is_dma_sync;

    SYS_STATS_DBG_FUNC();
    SYS_STATS_INIT_CHECK();
    CTC_PTR_VALID_CHECK(p_acl_change);

    is_dma_sync = sys_usw_dma_get_flow_stats_sync_mode(lchip);
    sal_memset(&sts_param, 0, sizeof(sts_param));

    statsid.stats_id = p_acl_change->stats_id;
    SYS_MAP_LCHIP_WITH_LOCK(lchip, pp_base, SYS_STATS_TYPE_ACL, CTC_INGRESS)
    p_statsid_res = ctc_hash_lookup(usw_flow_stats_master[lchip]->flow_stats_id_hash, &statsid);
    if (p_statsid_res == NULL)
    {
        SYS_STATS_DBG_ERROR(" Entry not exist \n");
        CTC_ERROR_RETURN_UNLOCK(CTC_E_NOT_EXIST);
    }
    p_statsid_acl = (sys_stats_statsid_acl_t*)p_statsid_res;

    if( p_statsid_acl->acl_priority == p_acl_change->new_block_id || SYS_STATS_IS_STABLE_EN(p_statsid_res->stats_ptr)
        || p_statsid_res->stats_id_type != SYS_STATS_TYPE_ACL )
    {
        STATS_UNLOCK(lchip);
        return CTC_E_NONE;
    }

    old_stats_ptr = p_statsid_res->stats_ptr;

    /* 1. alloc new stats_ptr */
    sts_param.acl_pri = p_acl_change->new_block_id;
    sts_param.type = SYS_STATS_TYPE_ACL;
    sts_param.dir = p_statsid_res->dir;
    sts_param.id = p_statsid_res->stats_id;
    sts_param.num = (p_statsid_acl->color_aware ? 3: 1);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_STATSID, 1);
    CTC_ERROR_GOTO(_sys_usw_flow_stats_alloc_statsptr(lchip, &sts_param), ret, exit);
    CTC_ERROR_GOTO(_sys_usw_flow_stats_entry_create(lchip, sts_param.num, sts_param.id, sts_param.ptr), ret, free_ptr);
    _sys_usw_flow_stats_clear_stats(lchip, sts_param.num, sts_param.ptr);
    p_statsid_res->stats_ptr = sts_param.ptr;
    p_statsid_acl->acl_priority = p_acl_change->new_block_id;


    /* 2. update acl entry's stats_ptr */
    ram = SYS_STATS_DECODE_PTR_RAM(p_statsid_res->stats_ptr);
    if(p_acl_change->cb)
    {
        uint32 acl_ststs_ptr = SYS_STATS_DECODE_PTR_OFFSET(p_statsid_res->stats_ptr);
        uint8 stats_pool = _sys_usw_flow_stats_encode_hw_ram(lchip, ram, p_statsid_res->dir);

        /* tm & d2 need encode ptr_hw */
        if(!DRV_FROM_TMM(lchip))
        {
            acl_ststs_ptr = _sys_usw_flow_stats_encode_hw_ptr(lchip, ram, acl_ststs_ptr);
        }
        p_acl_change->cb(lchip, acl_ststs_ptr, stats_pool, p_acl_change->user_data);
    }

    /* 3 copy the count in old stats buf to new stats */
    /* 3.1  get HW cnt and soft buffe count of the old stats_ptr */
    CTC_ERROR_DUMP(_sys_usw_flow_stats_get_stats(lchip, old_stats_ptr, sts_param.num, count));

    do
    {
        tmp_stats_ptr = old_stats_ptr + loop;
        /* 3.2 get new stats soft buf cnt */
        CTC_ERROR_DUMP(_sys_usw_flow_stats_entry_lookup(lchip, p_statsid_res->stats_ptr + loop, &p_flow_stats));

        if (is_dma_sync)/* just dma sync mode need !!*/
        {
            ram_offset = SYS_STATS_DECODE_PTR_OFFSET(tmp_stats_ptr);
            blk_id = ram;
            if(DRV_FROM_TMM(lchip))
            {
                drv_usw_ftm_get_flow_stats_table_id(lchip, ram, &tbl_id);
                stats_offset = ram_offset*16;
            }
            else
            {
#if (0 == SDK_WORK_PLATFORM)
                /* 3.3  get HW cache count of the old stats_ptr,only for no TMM */
                CTC_ERROR_DUMP(_sys_usw_flow_stats_read_buf_count(lchip, ram_offset, ram, count+loop));
#endif
                tbl_id = DsStats_t;
                stats_offset = ram_offset*8;
            }
            /* 3.4  get DMA count of the old stats_ptr , must pp tbl*/
            CTC_ERROR_DUMP(sys_usw_dma_get_flow_stats_memory(lchip, blk_id,dma_data,NULL));
            if (dma_data[0] != NULL)
            {
                data_base = usw_flow_stats_master[lchip]->p_stats_ram[blk_id].pp_en ? lchip - pp_base : 0;
                pp_num = usw_flow_stats_master[lchip]->p_stats_ram[blk_id].pp_en ? 1 : pp_num;
                loop2 = 0;
                do
                {
                    hw_stats = (DsStats_m*)((uint8*)(dma_data[loop2+data_base]) + stats_offset);
                    MCHIP_F_STATS(lchip)->ds2count(lchip, tbl_id, (ds_t*)(hw_stats), &dma_count);

                    p_flow_stats->byte_count += dma_count.byte_count;
                    p_flow_stats->packet_count += dma_count.packet_count;
                    loop2++;
                }while(loop2 < SYS_DMA_FLOW_STATS_DESC_DEPTH*pp_num);
            }
        }

        /* 3.5  copy old stats to new stats cnt */
        p_flow_stats->byte_count += count[loop].byte_count;
        p_flow_stats->packet_count += count[loop].packet_count;
        loop++;
    }
    while(loop < sts_param.num);

    /* 4 remove the old stats-ptr */
    sts_param.ptr = old_stats_ptr;
    CTC_ERROR_DUMP(_sys_usw_flow_stats_free_statsptr(lchip, &sts_param));
    CTC_ERROR_DUMP(_sys_usw_flow_stats_entry_delete(lchip, sts_param.num, old_stats_ptr));

    STATS_UNLOCK(lchip);
    return CTC_E_NONE;

    /* rollback */
free_ptr:
    _sys_usw_flow_stats_free_statsptr(lchip, &sts_param);
exit:
    STATS_UNLOCK(lchip);
    return ret;
}

int32
sys_usw_flow_stats_enable_igs_port_discard_stats(uint8 lchip, uint8 enable)
{
    uint32 field_val = 0;
    uint32 cmd = 0;

    SYS_STATS_INIT_CHECK();

    STATS_LOCK(lchip);
    field_val = ((enable > 0) ? 1: 0);
    cmd = DRV_IOW(IpeFwdCtl_t, IpeFwdCtl_discardStatsByPort_f);
    CTC_ERROR_RETURN_UNLOCK(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
    field_val = ((enable > 0) ? 1: 0);
    cmd = DRV_IOW(IpeFwdDiscardStatsCtl_t, IpeFwdDiscardStatsCtl_clearOnRead_f);
    CTC_ERROR_RETURN_UNLOCK(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));

    STATS_UNLOCK(lchip);
    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_clear_igs_port_discard_stats(uint8 lchip, uint32 gport)
{
    uint16 i = 0;
    uint16 lport = 0;
    uint32 cmd = 0;
    ds_t   ds;
    uint32 base = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    SYS_STATS_INIT_CHECK();

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);

    STATS_LOCK(lchip);
    if (DRV_FROM_TMM(lchip))
    {
        base = lport;
    }
    else
    {
        dmps_port_info.gport = gport;
        CTC_ERROR_RETURN_UNLOCK(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, (void *)&base));
    }
    base = base << 6;
    sal_memset(ds, 0, sizeof(ds_t));
    cmd = DRV_IOW(DsIngressDiscardStats_t, DRV_ENTRY_FLAG);

    for (i=SYS_STATS_IPE_DISCARD_TYPE_START; i<=SYS_STATS_IPE_DISCARD_TYPE_END; i++)
    {
        DRV_IOCTL(lchip, base+i, DRV_CMD_PP_EN(cmd), &ds);
    }
    STATS_UNLOCK(lchip);
    return CTC_E_NONE;
}


int32
sys_usw_flow_stats_enable_egs_port_discard_stats(uint8 lchip, uint8 enable)
{
    uint32 field_val = 0;
    uint32 cmd = 0;

    SYS_STATS_INIT_CHECK();
    STATS_LOCK(lchip);
    field_val = ((enable > 0) ? 1: 0);
    cmd = DRV_IOW(EpeHeaderEditCtl_t, EpeHeaderEditCtl_discardStatsByPort_f);
    CTC_ERROR_RETURN_UNLOCK(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
    field_val = ((enable > 0) ? 1: 0);
    cmd = DRV_IOW(EpeHdrEditMiscCtl_t, EpeHdrEditMiscCtl_clearOnRead_f);
    CTC_ERROR_RETURN_UNLOCK(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
    STATS_UNLOCK(lchip);
    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_clear_egs_port_discard_stats(uint8 lchip, uint32 gport)
{
    uint16 i = 0;
    uint32 chan_id = 0;
    uint16 lport = 0;
    uint32 cmd = 0;
    ds_t   ds;
    uint32 base = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    SYS_STATS_INIT_CHECK();

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    if (DRV_FROM_TMM(lchip))
    {
        base = lport << 6;
    }
    else
    {
        dmps_port_info.gport = gport;
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, (void *)&chan_id));
        base = (chan_id << 5) + (chan_id << 4) + (chan_id << 3);
    }
    sal_memset(ds, 0, sizeof(ds_t));
    cmd = DRV_IOW(DsEgressDiscardStats_t, DRV_ENTRY_FLAG);

    for (i=0; i<SYS_STATS_EPE_DISCARD_TYPE_MAX; i++)
    {
        DRV_IOCTL(lchip, base+i, DRV_CMD_PP_EN(cmd), &ds);
    }

    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_alloc_statsptr(uint8 lchip, sys_stats_param_t* p_st )
{
    int32 ret = 0;
    sys_stats_statsid_t statsid;
    sys_stats_statsid_t* p_st_res = &statsid;
    uint8 pp_base = SYS_PP_BASE(lchip);
    uint8 ram = 0;
    uint8 stable_en = 0;
    uint8 flag = (p_st->type == SYS_STATS_TYPE_QUEUE || p_st->type == SYS_STATS_TYPE_QUEUE_MC ||
                  p_st->type == SYS_STATS_TYPE_DMA || p_st->type == SYS_STATS_TYPE_DMA_MC ||
                  p_st->type == SYS_STATS_TYPE_PORTTC || p_st->type == SYS_STATS_TYPE_PORTTC_MC)? SYS_STATS_PTR_FLAG_CREATE_ON_INIT :0;
    uint16 ptr_offset = 0;
    uint8 stats_ptr_valid = 0;
    uint8 ptr_nto1_error = 0;

    SYS_STATS_DBG_FUNC();
    SYS_STATS_INIT_CHECK();

    p_st->num = p_st->num ? p_st->num : 1;
    if(p_st->id == 0 && p_st->type > SYS_STATS_TYPE_PORTTC_MC  && 
                        p_st->type != SYS_STATS_TYPE_POLICER0 && 
                        p_st->type != SYS_STATS_TYPE_POLICER1 )
    {
        return CTC_E_INVALID_PARAM;
    }

    SYS_MAP_LCHIP_WITH_LOCK(lchip, pp_base, p_st->type, p_st->dir);    
    /* 1. get stats_id node, and check param */
    if(p_st->id)
    {
        sal_memset(&statsid, 0, sizeof(sys_stats_statsid_t));
        statsid.stats_id = p_st->id;
        p_st_res = ctc_hash_lookup(usw_flow_stats_master[lchip]->flow_stats_id_hash, &statsid);
        if (p_st_res == NULL)
        {
            ret = CTC_E_NOT_EXIST;
            goto done;
        }
        /* npm stats both dir valid */
        if(p_st_res->stats_id_type != SYS_STATS_TYPE_SDC && (p_st_res->stats_id_type != p_st->type || (p_st_res->dir != p_st->dir && p_st->type != SYS_STATS_TYPE_NPM_IM)))
        {
            ret = CTC_E_INVALID_PARAM;
            goto done;
        }
        if(p_st_res->stats_id_type == SYS_STATS_TYPE_SDC)
        {
            p_st->type = SYS_STATS_TYPE_SDC;
        }
        stats_ptr_valid = p_st_res->stats_ptr_valid;
        if(p_st->type == SYS_STATS_TYPE_ACL)
        {
            sys_stats_statsid_acl_t* p_acl_st = (sys_stats_statsid_acl_t*) p_st_res;
            stable_en = SYS_STATS_IS_STABLE_EN(p_st_res->stats_ptr);
            if(stable_en)
            {
                p_st->flag |= SYS_STATS_FLAG_ACL_STABLE;
            }
            else
            {
                ptr_nto1_error = stats_ptr_valid;
                p_acl_st->acl_priority = p_st->acl_pri;
            }
            p_st->num = p_acl_st->color_aware ? 3 : 1;
            p_st->acl_pri = p_acl_st->acl_priority;
        }
        else if(p_st->type == SYS_STATS_TYPE_ECMP || p_st->type == SYS_STATS_TYPE_HECMP)
        {
            p_st->ptr = usw_flow_stats_master[SYS_PP_BASE(lchip)]->ecmp_base_ptr[p_st->type == SYS_STATS_TYPE_HECMP] + p_st->ptr;
            ptr_nto1_error = stats_ptr_valid;
        }
        else if(p_st->type == SYS_STATS_TYPE_FID)
        {
            p_st->ptr = usw_flow_stats_master[lchip]->fid_base_ptr[p_st->dir] + p_st->ptr;
            ptr_nto1_error = stats_ptr_valid;
        }
        else if(p_st->type == SYS_STATS_TYPE_NPM_IM && p_st->dir == CTC_EGRESS)
        {
            stats_ptr_valid = STATS_SHARE_NPM_PTR(p_st_res)->egs_stats_ptr_valid;
        }
        if(ptr_nto1_error)
        {
            ret = CTC_E_IN_USE;
            goto done;
        }
    }

    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_MASTER, 1);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_STATSID, 1);
    /* 2. alloc stats_ptr and create stats_ptr entry */
    if(!stats_ptr_valid)
    {
        if(p_st->type != SYS_STATS_TYPE_ECMP && p_st->type != SYS_STATS_TYPE_FID && p_st->type != SYS_STATS_TYPE_HECMP)
        {
            CTC_ERROR_GOTO( _sys_usw_flow_stats_alloc_statsptr(lchip, p_st), ret, done);
        }
        CTC_ERROR_GOTO( _sys_usw_flow_stats_entry_create(lchip, p_st->num, p_st->id, p_st->ptr), ret, free_ptr);
        if (0 == flag)
        {
            _sys_usw_flow_stats_clear_stats(lchip, p_st->num, p_st->ptr);
        }

        if(p_st->type == SYS_STATS_TYPE_NPM_IM && p_st->dir == CTC_EGRESS)
        {
            STATS_SHARE_NPM_PTR(p_st_res)->egs_stats_ptr = p_st->ptr;
            STATS_SHARE_NPM_PTR(p_st_res)->egs_stats_ptr_valid = 1;
        }
        else
        {
            p_st_res->stats_ptr = p_st->ptr;
            p_st_res->stats_ptr_valid = 1;
        }
        /* for warmboot, mark npm only need one stats_ptr */
        if(p_st->type == SYS_STATS_TYPE_NPM_IM && p_st->num == 1 && p_st->acl_pri == 0xff)
        {
            STATS_SHARE_NPM_PTR(p_st_res)->egs_stats_ptr = 0xFFFF;
        }
    }

    STATS_UNLOCK(lchip);

    /* 3. encode hw stats_ptr */
    if(p_st->type == SYS_STATS_TYPE_NPM_IM)
    {
        p_st->ptr = p_st->dir == CTC_EGRESS ? STATS_SHARE_NPM_PTR(p_st_res)->egs_stats_ptr : p_st_res->stats_ptr;
    }
    else
    {
        ram = SYS_STATS_DECODE_PTR_RAM(p_st_res->stats_ptr);
        ptr_offset = SYS_STATS_DECODE_PTR_OFFSET(p_st_res->stats_ptr);
        p_st->ptr = _sys_usw_flow_stats_encode_hw_ptr(lchip, ram, ptr_offset);

        if(p_st->type == SYS_STATS_TYPE_ACL)
        {
            p_st->ram_id = _sys_usw_flow_stats_encode_hw_ram(lchip, ram, p_st_res->dir);
            SYS_STATS_SET_STABLE_EN(p_st_res->stats_ptr, stable_en);
        }
        else if(p_st->type == SYS_STATS_TYPE_FLOW_HASH )
        {
            uint32 cmd = DRV_IOR(IpeFlowHashCtl_t, IpeFlowHashCtl_igrIpfix32KMode_f);
            uint32 field_val = 0;
            DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val);
            if(!field_val)
            {
                return CTC_E_NONE;
            }
            p_st->ptr = (uint32)SYS_STATS_ENCODE_CHIP_32K_PTR(ram, ptr_offset);
            if( ram >= SYS_STATS_RAM_EPE_GLOBAL0 && ram <= SYS_STATS_RAM_EPE_GLOBAL3)
            {
                p_st->ptr |= (1<<14);
            }
        }
    }

    SYS_STATS_DBG_INFO("stats_ptr:0x%04X\n", p_st->ptr);

    return CTC_E_NONE;

free_ptr:
    _sys_usw_flow_stats_free_statsptr(lchip, p_st);
done:
    STATS_UNLOCK(lchip);
    return ret;
}


/* free stats_ptr by stats_id or stats_ptr */
int32
sys_usw_flow_stats_free_statsptr(uint8 lchip, sys_stats_param_t* p_st)
{
    uint8 ram = 0;
    uint8 ptr_valid = 0;
    uint8 pp_base = SYS_PP_BASE(lchip);
    uint32 stats_ptr = 0;
    sys_stats_statsid_t statsid;
    sys_stats_statsid_t* p_statsid_res = NULL;

    SYS_STATS_DBG_FUNC();
    SYS_STATS_INIT_CHECK();
    CTC_PTR_VALID_CHECK(p_st);

    SYS_MAP_LCHIP_WITH_LOCK(lchip, pp_base, p_st->type, p_st->dir);
    p_st->num = p_st->num ? p_st->num : 1;

    /* 1. decode stats_ptr*/
    if(p_st->ptr)
    {
        sys_stats_flow_stats_t* p_stats = NULL;
        /* ecmp and fid stats_ptr for ecmp_grp and fid */
        if(p_st->type == SYS_STATS_TYPE_ECMP || p_st->type == SYS_STATS_TYPE_HECMP)
        {
            stats_ptr = usw_flow_stats_master[SYS_PP_BASE(lchip)]->ecmp_base_ptr[p_st->type == SYS_STATS_TYPE_HECMP] + p_st->ptr;
        }
        else if (p_st->type == SYS_STATS_TYPE_FID)
        {
            stats_ptr = usw_flow_stats_master[lchip]->fid_base_ptr[p_st->dir] + p_st->ptr;
        }
        else
        {
            ram = _sys_usw_flow_stats_decode_hw_ptr(lchip, p_st->type, p_st->dir, p_st->ptr);
            stats_ptr = SYS_STATS_ENCODE_SYS_PTR(ram, DRV_IS_DUET2(lchip)?(p_st->ptr)&0xFFF:(p_st->ptr)&0x1FFF);
        }
        ram = SYS_STATS_DECODE_PTR_RAM(stats_ptr);

        /* policer&queue stats has no ptr entry */
        p_stats = ctc_vector_get(usw_flow_stats_master[lchip]->flow_stats_vec[ram], (stats_ptr &0xffff));
        p_st->id = p_stats ? p_stats->stats_id : 0;
    }

    /* 2. get stats_id entry */
    if(p_st->id)
    {
        sal_memset(&statsid, 0, sizeof(statsid));
        statsid.stats_id = p_st->id;
        p_statsid_res = ctc_hash_lookup(usw_flow_stats_master[lchip]->flow_stats_id_hash, &statsid);
        if (p_statsid_res == NULL || (p_st->type && p_statsid_res->stats_id_type != p_st->type))
        {
            SYS_STATS_DBG_ERROR(" Entry not exist \n");
            STATS_UNLOCK(lchip);
            return CTC_E_NOT_EXIST;
        }

        stats_ptr = p_statsid_res->stats_ptr;
        ptr_valid = p_statsid_res->stats_ptr_valid;
        p_st->type = p_statsid_res->stats_id_type;
        if(p_st->type == SYS_STATS_TYPE_NPM_IM)
        {
            if(p_st->dir == CTC_EGRESS)
            {
                stats_ptr = STATS_SHARE_NPM_PTR(p_statsid_res)->egs_stats_ptr;
                ptr_valid = STATS_SHARE_NPM_PTR(p_statsid_res)->egs_stats_ptr_valid;
            }
            p_st->num = 2;
        }
        else if(p_st->type == SYS_STATS_TYPE_ACL)
        {
            p_st->num = STATS_SHARE_ACL_PTR(p_statsid_res)->color_aware ?  3 : 1;
            ptr_valid = p_statsid_res->stats_ptr_valid && !SYS_STATS_IS_STABLE_EN(p_statsid_res->stats_ptr);
        }

        if(!ptr_valid)
        {
            STATS_UNLOCK(lchip);
            return CTC_E_NONE;
        }
    }

    /* 3. clear, del ptr entry and free stats_ptr */
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_STATSID, 1);
    _sys_usw_flow_stats_clear_stats(lchip, p_st->num, stats_ptr);
    CTC_ERROR_DUMP(_sys_usw_flow_stats_entry_delete(lchip, p_st->num, stats_ptr));
    /* fid and ecmp use rsv stats_ptr */
    if( p_st->type != SYS_STATS_TYPE_FID &&
        p_st->type != SYS_STATS_TYPE_ECMP &&
        p_st->type != SYS_STATS_TYPE_HECMP)
    {
        p_st->ptr = stats_ptr;
        _sys_usw_flow_stats_free_statsptr(lchip, p_st);
    }

    /*4. clear stats_ptr in stats_id entry */
    if(p_statsid_res)
    {
        if(p_st->dir == CTC_EGRESS && p_st->type == SYS_STATS_TYPE_NPM_IM)
        {
            STATS_SHARE_NPM_PTR(p_statsid_res)->egs_stats_ptr = 0;
            STATS_SHARE_NPM_PTR(p_statsid_res)->egs_stats_ptr_valid = 0;
        }
        else
        {
            p_statsid_res->stats_ptr = 0;
            p_statsid_res->stats_ptr_valid = 0;
        }
    }

    STATS_UNLOCK(lchip);

    SYS_STATS_DBG_INFO("stats_ptr:0x%08X\n", p_st->ptr);
    return CTC_E_NONE;
}


int32
sys_usw_flow_stats_sync_queue_stats(uint8 lchip, uint32 stats_ptr1, uint32 stats_ptr2)
{
    sys_stats_flow_stats_t* p_fwd_stats = NULL;
    ctc_stats_basic_t count;
    uint32 base_ptr = 0;

    STATS_LOCK(lchip);

    base_ptr = SYS_STATS_ENCODE_SYS_PTR(SYS_STATS_RAM_QUE, 0);
    CTC_ERROR_RETURN_UNLOCK(_sys_usw_flow_stats_entry_lookup(lchip, base_ptr + (stats_ptr1&0xFFFF), &p_fwd_stats));
    CTC_ERROR_RETURN_UNLOCK(_sys_usw_flow_stats_get_stats(lchip, base_ptr + (stats_ptr2&0xFFFF), 1, &count));
    CTC_ERROR_RETURN_UNLOCK(_sys_usw_flow_stats_clear_stats(lchip, 1, base_ptr + (stats_ptr2&0xFFFF)));
    p_fwd_stats->packet_count += count.packet_count;
    p_fwd_stats->byte_count += count.byte_count;

    STATS_UNLOCK(lchip);

    return CTC_E_NONE;
}

/*get 8(basic) + 4(ctl) queue stats of port*/
int32
sys_usw_flow_stats_get_queue_stats2(uint8 lchip, uint32 gport, uint16 queue_id, ctc_qos_queue_stats_info_t* p_stats)
{
    uint32 base_ptr = 0;
    uint32 stats_ptr = 0;
    uint32 cmd = 0;
    uint32 channel = 0;
    uint8  loop = 0;
    ctc_stats_basic_t count;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    SYS_STATS_DBG_FUNC();
    SYS_STATS_INIT_CHECK();
    dmps_port_info.gport = gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &channel));

    if (!SYS_IS_NETWORK_CHANNEL(channel))
    {
        SYS_STATS_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }
    MCHIP_DMA(lchip)->dma_stats_func(lchip, SYS_DMA_FLOW_STATS_CHAN_ID);
    STATS_LOCK(lchip);

    if (DRV_FROM_TMM(lchip))
    {
        base_ptr = SYS_STATS_ENCODE_SYS_PTR(SYS_STATS_RAM_QUE, 0);
    }
    else
    {
        base_ptr = usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_QUEUE].base_ptr;
    }
    sal_memset(&count,0, sizeof(ctc_stats_basic_t));

    for (loop=0; loop<MCHIP_CAP(SYS_CAP_QOS_NORMAL_QUEUE_NUM); loop++)
    {
        if (DRV_IS_TSINGMA(lchip))
        {
            cmd = DRV_IOR(DsErmQueueCfg_t, DsErmQueueCfg_statsPtr_f);
            CTC_ERROR_RETURN_UNLOCK(DRV_FIELD_IOCTL(lchip, queue_id+loop, cmd, &stats_ptr));

            CTC_ERROR_RETURN_UNLOCK(_sys_usw_flow_stats_get_stats(lchip, base_ptr + ((stats_ptr+1)&0xFFFF), 1, &count));
            p_stats->drop_packets += count.packet_count;
            p_stats->drop_bytes   += count.byte_count;

            CTC_ERROR_RETURN_UNLOCK(_sys_usw_flow_stats_get_stats(lchip, base_ptr + (stats_ptr&0xFFFF), 1, &count));
            p_stats->deq_packets += count.packet_count;
            p_stats->deq_bytes   += count.byte_count;
        }
        else
        {
            stats_ptr = queue_id+loop;
            CTC_ERROR_RETURN_UNLOCK(_sys_usw_flow_stats_get_stats(lchip, base_ptr + (stats_ptr&0xFFFF), 1, &count));
            p_stats->drop_packets += count.packet_count;
            p_stats->deq_packets  += count.byte_count;
        }
    }

    queue_id = MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM);

    for (loop=0; loop<MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM); loop++)
    {
        if (DRV_IS_TSINGMA(lchip))
        {
            cmd = DRV_IOR(DsErmQueueCfg_t, DsErmQueueCfg_statsPtr_f);
            CTC_ERROR_RETURN_UNLOCK(DRV_FIELD_IOCTL(lchip, queue_id+loop, cmd, &stats_ptr));

            CTC_ERROR_RETURN_UNLOCK(_sys_usw_flow_stats_get_stats(lchip, base_ptr + ((stats_ptr+1)&0xFFFF), 1, &count));
            p_stats->drop_packets += count.packet_count;
            p_stats->drop_bytes   += count.byte_count;

            CTC_ERROR_RETURN_UNLOCK(_sys_usw_flow_stats_get_stats(lchip, base_ptr + (stats_ptr&0xFFFF), 1, &count));
            p_stats->deq_packets += count.packet_count;
            p_stats->deq_bytes   += count.byte_count;
        }
        else
        {
            stats_ptr = queue_id+loop;
            CTC_ERROR_RETURN_UNLOCK(_sys_usw_flow_stats_get_stats(lchip, base_ptr + (stats_ptr&0xFFFF), 1, &count));
            p_stats->drop_packets += count.packet_count;
            p_stats->deq_packets  += count.byte_count;
        }
    }
    STATS_UNLOCK(lchip);

    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_set_drop_packet_stats_en(uint8 lchip, ctc_stats_discard_t bitmap, bool enable)
{
    uint32 cmd = 0;
    uint32 tmp = 0;
    uint32  care_discard = 0;

    SYS_STATS_DBG_FUNC();

    SYS_STATS_INIT_CHECK();

    tmp = 0;
    if (0 != (bitmap & CTC_STATS_FLOW_DISCARD_STATS))
    {
        tmp = (enable) ? 1 : 0;

        care_discard = (enable) ? 0x3 : 0;
        cmd = DRV_IOW(IpeSclFlowCtl_t, IpeSclFlowCtl_sclStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &care_discard));

        cmd = DRV_IOW(IpeIntfMapperCtl_t, IpeIntfMapperCtl_srcInterfacestatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        cmd = DRV_IOW(IpeIntfMapperCtl_t, IpeIntfMapperCtl_srcVlanStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        cmd = DRV_IOW(IpeTunnelDecapCtl_t, IpeTunnelDecapCtl_tunnelStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        cmd = DRV_IOW(IpeBridgeCtl_t, IpeBridgeCtl_macdaStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        cmd = DRV_IOW(IpeFwdCtl_t, IpeFwdCtl_fwdStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        care_discard = (enable) ? 0xF : 0;
        cmd = DRV_IOW(IpeUserIdCtl_t, IpeUserIdCtl_userIdstatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &care_discard));

        care_discard = (enable) ? 0x1 : 0;
        cmd = DRV_IOW(IpePktProcCtl_t, IpePktProcCtl_vsiStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &care_discard));

        care_discard = (enable) ? 0x7 : 0;
        cmd = DRV_IOW(IpeMplsCtl_t, IpeMplsCtl_statsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &care_discard));

        cmd = DRV_IOW(IpeFlowHashCtl_t, IpeFlowHashCtl_statsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        cmd = DRV_IOW(IpeRouteCtl_t, IpeRouteCtl_vrfStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        cmd = DRV_IOW(IpeRouteCtl_t, IpeRouteCtl_ipdaStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        cmd = DRV_IOW(IpeEcmpCtl_t, IpeEcmpCtl_ecmpStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
        cmd = DRV_IOW(IpeEcmpCtl_t, IpeEcmpCtl_ecmpMemberStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        care_discard = (enable) ? 0xFF : 0;
        cmd = DRV_IOW(IpeFwdCtl_t, IpeFwdCtl_aclStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &care_discard));
        cmd = DRV_IOW(IpeAclQosCtl_t, IpeAclQosCtl_aclStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &care_discard));

        /*EPE stats*/
        cmd = DRV_IOW(EpeNextHopCtl_t, EpeNextHopCtl_nhpStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        care_discard = (enable) ? 0x3 : 0;
        cmd = DRV_IOW(EpeNextHopCtl_t, EpeNextHopCtl_xlateStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &care_discard));

        cmd = DRV_IOW(EpePktProcCtl_t, EpePktProcCtl_vsiStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &care_discard));

        cmd = DRV_IOW(EpeNextHopCtl_t, EpeNextHopCtl_vlanStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        cmd = DRV_IOW(EpeNextHopCtl_t, EpeNextHopCtl_destInfStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        cmd = DRV_IOW(EpeNextHopCtl_t, EpeNextHopCtl_nshStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        cmd = DRV_IOW(EpePktProcCtl_t, EpePktProcCtl_l3edit0StatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        cmd = DRV_IOW(EpePktProcCtl_t, EpePktProcCtl_l3edit1StatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        cmd = DRV_IOW(EpePktProcCtl_t, EpePktProcCtl_l3edit2StatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        care_discard = (enable) ? 0x7 : 0;
        cmd = DRV_IOW(EpeAclQosCtl_t, EpeAclQosCtl_aclStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &care_discard));
    }

    if (0 != (bitmap & CTC_STATS_RANDOM_LOG_DISCARD_STATS))
    {
        tmp = (enable) ? 1 : 0;

        cmd = DRV_IOW(IpeFwdCtl_t, IpeFwdCtl_portStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));

        cmd = DRV_IOW(EpeHeaderEditCtl_t, EpeHeaderEditCtl_portStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
    }

    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_get_drop_packet_stats_en(uint8 lchip, ctc_stats_discard_t bitmap, bool* enable)
{
    uint32 cmd = 0, tmp = 0;

    SYS_STATS_DBG_FUNC();

    SYS_STATS_INIT_CHECK();
    CTC_PTR_VALID_CHECK(enable);

    *enable = FALSE;

    switch (bitmap & (CTC_STATS_RANDOM_LOG_DISCARD_STATS | CTC_STATS_FLOW_DISCARD_STATS))
    {
    case CTC_STATS_FLOW_DISCARD_STATS:
        cmd = DRV_IOR(IpeFwdCtl_t, IpeFwdCtl_fwdStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
        *enable = (tmp) ? TRUE : FALSE;
        break;
    case CTC_STATS_RANDOM_LOG_DISCARD_STATS:
        cmd = DRV_IOR(IpeFwdCtl_t, IpeFwdCtl_portStatsCareDiscard_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
        *enable = (tmp) ? TRUE : FALSE;
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_set_saturate_en(uint8 lchip, ctc_stats_type_t stats_type, bool enable)
{
    uint32 cmd = 0;
    uint32 tmp = 0;
    uint8 index=0;
    uint8 step=0;
    SYS_STATS_INIT_CHECK();
    SYS_STATS_TYPE_CHECK(stats_type);

    tmp = (FALSE == enable) ? 0 : 1;
    SYS_STATS_DBG_FUNC();
    SYS_STATS_DBG_INFO( "enable:%d\n", enable);

    switch (stats_type)
    {
    case CTC_STATS_TYPE_FWD:
        /*DS STATS*/
        if (DRV_FROM_TMM(lchip))
        {
            step = GlobalStatsCtl_global1StatsSaturateEn_f - GlobalStatsCtl_global0StatsSaturateEn_f;
            for (index = 0; index < MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM); index++)
            {
                cmd = DRV_IOW(GlobalStatsCtl_t, GlobalStatsCtl_ipeAcl0StatsSaturateEn_f + step*index);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
            }
            for (index = 0; index < MCHIP_CAP(SYS_CAP_ACL_EGRESS_LKUP_NUM) ; index++)
            {
                cmd = DRV_IOW(GlobalStatsCtl_t, GlobalStatsCtl_epeAcl0StatsSaturateEn_f + step*index);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
            }
            for (index = 0; index < MCHIP_CAP(SYS_CAP_STATS_GLOBAL_RAM_NUM); index++)
            {
                cmd = DRV_IOW(GlobalStatsCtl_t, GlobalStatsCtl_global0StatsSaturateEn_f + step*index);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
            }
        }
        else
        {
            cmd = DRV_IOW(GlobalStatsCtl_t, GlobalStatsCtl_saturateEn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
        }
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_get_saturate_en(uint8 lchip, ctc_stats_type_t stats_type, bool* p_enable)
{
    uint32 cmd = 0;
    uint32 tmp = 0;

    SYS_STATS_DBG_FUNC();

    SYS_STATS_INIT_CHECK();
    SYS_STATS_TYPE_CHECK(stats_type);

    switch (stats_type)
    {
    case CTC_STATS_TYPE_FWD:
        /*DS STATS*/
        if (DRV_FROM_TMM(lchip))
        {
             cmd = DRV_IOR(GlobalStatsCtl_t, GlobalStatsCtl_epeAcl0StatsSaturateEn_f);
        }
        else
        {
            cmd = DRV_IOR(GlobalStatsCtl_t, GlobalStatsCtl_saturateEn_f);
        }
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    *p_enable = (tmp>0 ? TRUE: FALSE);

    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_set_keep_mode(uint8 lchip, ctc_stats_type_t stats_type, bool enable)
{
    uint32 cmd = 0;
    uint32 tmp = 0;
    uint8 index=0;
    uint8 step=0;
    SYS_STATS_INIT_CHECK();
    SYS_STATS_TYPE_CHECK(stats_type);

    tmp = (FALSE == enable) ? 0 : 1;
    SYS_STATS_DBG_FUNC();
    SYS_STATS_DBG_INFO( "enable:%d\n", enable);

    switch (stats_type)
    {
        case CTC_STATS_TYPE_FWD:
            /*DS STATS*/
            step = GlobalStatsCtl_global1StatsKeepMode_f - GlobalStatsCtl_global0StatsKeepMode_f;
            for (index = 0; index < MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM); index++)
            {
                cmd = DRV_IOW(GlobalStatsCtl_t, GlobalStatsCtl_ipeAcl0StatsKeepMode_f + step*index);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
            }
            for (index = 0; index < MCHIP_CAP(SYS_CAP_ACL_EGRESS_LKUP_NUM) ; index++)
            {
                cmd = DRV_IOW(GlobalStatsCtl_t, GlobalStatsCtl_epeAcl0StatsKeepMode_f + step*index);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
            }
            for (index = 0; index < MCHIP_CAP(SYS_CAP_STATS_GLOBAL_RAM_NUM); index++)
            {
                cmd = DRV_IOW(GlobalStatsCtl_t, GlobalStatsCtl_global0StatsKeepMode_f + step*index);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
            }
            break;

        default:
            return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_get_keep_mode(uint8 lchip, ctc_stats_type_t stats_type, bool* p_enable)
{
    uint32 cmd = 0;
    uint32 tmp = 0;

    SYS_STATS_DBG_FUNC();

    SYS_STATS_INIT_CHECK();
    SYS_STATS_TYPE_CHECK(stats_type);

    switch (stats_type)
    {
        case CTC_STATS_TYPE_FWD:
            /*DS STATS*/
           cmd = DRV_IOR(GlobalStatsCtl_t, GlobalStatsCtl_global0StatsKeepMode_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
            break;

        default:
            return CTC_E_INVALID_PARAM;
    }
    *p_enable = (tmp>0 ? TRUE: FALSE);

    return CTC_E_NONE;
}


int32
sys_usw_flow_stats_set_hold_en(uint8 lchip, ctc_stats_type_t stats_type, bool enable)
{
    uint32 cmd = 0;
    uint32 tmp = 0;
    uint8 index=0;
    uint8 step=0;

    SYS_STATS_DBG_FUNC();

    SYS_STATS_INIT_CHECK();
    SYS_STATS_TYPE_CHECK(stats_type);

    tmp = (FALSE == enable) ? 0 : 1;
    switch (stats_type)
    {
    case CTC_STATS_TYPE_FWD:
        /*DS STATS*/
        if (DRV_FROM_TMM(lchip))
        {
            step = GlobalStatsCtl_global1StatsStatsHold_f - GlobalStatsCtl_global0StatsStatsHold_f;
            for (index = 0; index < MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM); index++)
            {
                cmd = DRV_IOW(GlobalStatsCtl_t, GlobalStatsCtl_ipeAcl0StatsStatsHold_f + step*index);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
            }
            for (index = 0; index < MCHIP_CAP(SYS_CAP_ACL_EGRESS_LKUP_NUM); index++)
            {
                cmd = DRV_IOW(GlobalStatsCtl_t, GlobalStatsCtl_epeAcl0StatsStatsHold_f + step*index);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
            }
            for (index = 0; index < MCHIP_CAP(SYS_CAP_STATS_GLOBAL_RAM_NUM); index++)
            {
                cmd = DRV_IOW(GlobalStatsCtl_t, GlobalStatsCtl_global0StatsStatsHold_f + step*index);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
            }
        }
        else
        {
            cmd = DRV_IOW(GlobalStatsCtl_t, GlobalStatsCtl_statsHold_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
        }
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_get_hold_en(uint8 lchip, ctc_stats_type_t stats_type, bool* p_enable)
{
    uint32 cmd = 0;
    uint32 tmp = 0;

    SYS_STATS_DBG_FUNC();

    SYS_STATS_INIT_CHECK();
    SYS_STATS_TYPE_CHECK(stats_type);

    switch (stats_type)
    {
    case CTC_STATS_TYPE_FWD:
        /*DS STATS*/
        if (DRV_FROM_TMM(lchip))
        {
            cmd = DRV_IOR(GlobalStatsCtl_t, GlobalStatsCtl_epeAcl0StatsStatsHold_f);
        }
        else
        {
            cmd = DRV_IOR(GlobalStatsCtl_t, GlobalStatsCtl_statsHold_f);
        }

        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    *p_enable = (tmp>0 ? TRUE: FALSE);

    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_set_clear_after_read_en(uint8 lchip, ctc_stats_type_t stats_type, bool enable)
{
    uint32 cmd = 0;
    uint32 tmp = 0;
    uint8 step=0;
    uint8 index=0;


    SYS_STATS_INIT_CHECK();
    SYS_STATS_TYPE_CHECK(stats_type);

    tmp = (FALSE == enable) ? 0 : 1;

    SYS_STATS_DBG_FUNC();
    SYS_STATS_DBG_INFO( "enable:%d\n", enable);

    switch (stats_type)
    {
    case CTC_STATS_TYPE_FWD:
        /*DS STATS*/
        if (DRV_FROM_TMM(lchip))
        {
            step = GlobalStatsCtl_global1StatsClearOnRead_f - GlobalStatsCtl_global0StatsClearOnRead_f;
            for (index = 0; index < MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM); index++)
            {
                cmd = DRV_IOW(GlobalStatsCtl_t, GlobalStatsCtl_ipeAcl0StatsClearOnRead_f + step*index);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
            }
            for (index = 0; index < MCHIP_CAP(SYS_CAP_ACL_EGRESS_LKUP_NUM); index++)
            {
                cmd = DRV_IOW(GlobalStatsCtl_t, GlobalStatsCtl_epeAcl0StatsClearOnRead_f + step*index);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
            }
            for (index = 0; index < MCHIP_CAP(SYS_CAP_STATS_GLOBAL_RAM_NUM); index++)
            {
                cmd = DRV_IOW(GlobalStatsCtl_t, GlobalStatsCtl_global0StatsClearOnRead_f + step*index);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
            }
            cmd = DRV_IOW(QMgrErmQueStatsCtl_t, QMgrErmQueStatsCtl_queStatsClearOnRd_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
            if (DRV_FROM_AT(lchip))
            {
                cmd = DRV_IOW(BufStoreErmDsStatsCtl_t, BufStoreErmDsStatsCtl_queueStatsClearOnRd_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
                cmd = DRV_IOW(BufStoreErmDsStatsCtl_t, BufStoreErmDsStatsCtl_dmaStatsClearOnRd_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
            }
        }
        else
        {
            cmd = DRV_IOW(GlobalStatsCtl_t, GlobalStatsCtl_clearOnRead_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
        }
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    usw_flow_stats_master[lchip]->clear_read_en = enable;

    return CTC_E_NONE;

}

int32
sys_usw_flow_stats_get_clear_after_read_en(uint8 lchip, ctc_stats_type_t stats_type, bool* p_enable)
{
    uint32 cmd = 0;
    uint32 tmp = 0;

    SYS_STATS_INIT_CHECK();
    SYS_STATS_TYPE_CHECK(stats_type);

    SYS_STATS_DBG_FUNC();

    switch (stats_type)
    {
    case CTC_STATS_TYPE_FWD:
        /*DS STATS*/
        if (DRV_FROM_TMM(lchip))
        {
            cmd = DRV_IOR(GlobalStatsCtl_t, GlobalStatsCtl_epeAcl0StatsClearOnRead_f );
        }
        else
        {
            cmd = DRV_IOR(GlobalStatsCtl_t, GlobalStatsCtl_clearOnRead_f);
        }
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &tmp));
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    *p_enable = (tmp>0 ? TRUE: FALSE);

    return CTC_E_NONE;
}

uint32 stats_threashold_tbl[] =
{
    GlobalStatsEpeAclStatsUpdateThrdCtl0_t,
    GlobalStatsEpeAclStatsUpdateThrdCtl1_t,
    GlobalStatsEpeAclStatsUpdateThrdCtl2_t,
    GlobalStatsEpeAclStatsUpdateThrdCtl3_t,
    GlobalStatsEpeAclStatsUpdateThrdCtl4_t,
    GlobalStatsEpeAclStatsUpdateThrdCtl5_t,
    GlobalStatsEpeAclStatsUpdateThrdCtl6_t,
    GlobalStatsEpeAclStatsUpdateThrdCtl7_t,
    GlobalStatsEpeAclStatsUpdateThrdCtl8_t,
    GlobalStatsEpeAclStatsUpdateThrdCtl9_t,
    GlobalStatsEpeAclStatsUpdateThrdCtl10_t,
    GlobalStatsEpeAclStatsUpdateThrdCtl11_t,

    GlobalStatsIpeAclStatsUpdateThrdCtl0_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl1_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl2_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl3_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl4_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl5_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl6_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl7_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl8_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl9_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl10_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl11_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl12_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl13_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl14_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl15_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl16_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl17_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl18_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl19_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl20_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl21_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl22_t,
    GlobalStatsIpeAclStatsUpdateThrdCtl23_t,

    GlobalStatsGlobalUpdateThrdCtl0_t,
    GlobalStatsGlobalUpdateThrdCtl1_t,
    GlobalStatsGlobalUpdateThrdCtl2_t,
    GlobalStatsGlobalUpdateThrdCtl3_t,
    GlobalStatsGlobalUpdateThrdCtl4_t,
    GlobalStatsGlobalUpdateThrdCtl5_t,
    GlobalStatsGlobalUpdateThrdCtl6_t,
    GlobalStatsGlobalUpdateThrdCtl7_t,
    GlobalStatsGlobalUpdateThrdCtl8_t,
    GlobalStatsGlobalUpdateThrdCtl9_t,
    GlobalStatsGlobalUpdateThrdCtl10_t,
    GlobalStatsGlobalUpdateThrdCtl11_t,
    GlobalStatsGlobalUpdateThrdCtl12_t,
    GlobalStatsGlobalUpdateThrdCtl13_t,
    GlobalStatsGlobalUpdateThrdCtl14_t,
    GlobalStatsGlobalUpdateThrdCtl15_t
};

int32
sys_usw_flow_stats_set_pkt_cnt_threashold(uint8 lchip, ctc_stats_type_t stats_type, uint16 value)
{
    uint8 i = 0;
    uint32 tbl_id;
    uint32 cmd = 0;
    GlobalStatsEpeAclStatsUpdateThrdCtl0_m stats_thrd_ctl;
    SYS_STATS_INIT_CHECK();
    SYS_STATS_TYPE_CHECK(stats_type);

    SYS_STATS_DBG_FUNC();

    switch (stats_type)
    {
    case CTC_STATS_TYPE_FWD:
        for (i = 0; i < sizeof(stats_threashold_tbl)/sizeof(uint32); i++)
        {
            tbl_id = stats_threashold_tbl[i];
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &stats_thrd_ctl));
            SetGlobalStatsEpeAclStatsUpdateThrdCtl0(V, epeAcl0StatsPktCntThrd_f, &stats_thrd_ctl, value);
            cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &stats_thrd_ctl));
        }
        usw_flow_stats_master[lchip]->pkt_cnt_threashold = value <<14;/*AT for sync fifo statsptr*/
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;

}

int32
sys_usw_flow_stats_get_pkt_cnt_threashold(uint8 lchip, ctc_stats_type_t stats_type, uint16* value)
{
    SYS_STATS_INIT_CHECK();
    SYS_STATS_TYPE_CHECK(stats_type);

    SYS_STATS_DBG_FUNC();

    switch (stats_type)
    {
    case CTC_STATS_TYPE_FWD:
        *value = usw_flow_stats_master[lchip]->pkt_cnt_threashold >> 14;
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;

}

int32
sys_usw_flow_stats_set_byte_cnt_threashold(uint8 lchip, ctc_stats_type_t stats_type, uint16 value)
{
    uint8 i = 0;
    uint32 tbl_id;
    uint32 cmd = 0;
    GlobalStatsEpeAclStatsUpdateThrdCtl0_m stats_thrd_ctl;

    SYS_STATS_INIT_CHECK();
    SYS_STATS_TYPE_CHECK(stats_type);

    SYS_STATS_DBG_FUNC();

    switch (stats_type)
    {
    case CTC_STATS_TYPE_FWD:
        for (i = 0; i < sizeof(stats_threashold_tbl)/sizeof(uint32); i++)
        {
            tbl_id = stats_threashold_tbl[i];
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &stats_thrd_ctl));
            SetGlobalStatsEpeAclStatsUpdateThrdCtl0(V, epeAcl0StatsByteCntThrd_f, &stats_thrd_ctl, value);
            cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &stats_thrd_ctl));
        }
        usw_flow_stats_master[lchip]->byte_cnt_threashold = (uint64)value << 22;/*AT for sync fifo statsptr*/
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;

}

int32
sys_usw_flow_stats_get_byte_cnt_threashold(uint8 lchip, ctc_stats_type_t stats_type, uint16* value)
{
    SYS_STATS_INIT_CHECK();
    SYS_STATS_TYPE_CHECK(stats_type);

    SYS_STATS_DBG_FUNC();

    switch (stats_type)
    {
    case CTC_STATS_TYPE_FWD:
        *value = usw_flow_stats_master[lchip]->byte_cnt_threashold >> 22;
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;

}

int32
sys_usw_flow_stats_set_fifo_interrupt_threashold(uint8 lchip, ctc_stats_type_t stats_type, uint8 value)
{
    uint32 cmd = 0;
    GlobalStatsSatuInterruptThreshold_m stats_interrupt_thrd;
    SYS_STATS_INIT_CHECK();
    SYS_STATS_TYPE_CHECK(stats_type);

    SYS_STATS_DBG_FUNC();

    switch (stats_type)
    {
    case CTC_STATS_TYPE_FWD:
        CTC_VALUE_RANGE_CHECK(value, 1, CTC_CONST128-1);
        cmd = DRV_IOR(GlobalStatsSatuInterruptThreshold_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &stats_interrupt_thrd));
        SetGlobalStatsSatuInterruptThreshold(V, satuAddrFifoDepthThreshold_f, &stats_interrupt_thrd, value);
        cmd = DRV_IOW(GlobalStatsSatuInterruptThreshold_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &stats_interrupt_thrd));
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;

}

int32
sys_usw_flow_stats_get_fifo_interrupt_threashold(uint8 lchip, ctc_stats_type_t stats_type, uint8* value)
{
    uint32 cmd = 0;
    GlobalStatsSatuInterruptThreshold_m stats_interrupt_thrd;
    SYS_STATS_INIT_CHECK();
    SYS_STATS_TYPE_CHECK(stats_type);

    SYS_STATS_DBG_FUNC();

    switch (stats_type)
    {
    case CTC_STATS_TYPE_FWD:
        sal_memset(&stats_interrupt_thrd, 0, sizeof(GlobalStatsSatuInterruptThreshold_m));
        cmd = DRV_IOR(GlobalStatsSatuInterruptThreshold_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &stats_interrupt_thrd));
        *value = GetGlobalStatsSatuInterruptThreshold(V, satuAddrFifoDepthThreshold_f, &stats_interrupt_thrd);
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;

}

int32
sys_usw_flow_stats_create_statsid(uint8 lchip, ctc_stats_statsid_t* p_ctc_statsid)
{
    uint8 type = 0;
    uint8 dir = 0;
    sys_stats_statsid_acl_t  sys_statsid;

    SYS_STATS_DBG_FUNC();
    SYS_STATS_INIT_CHECK();
    CTC_PTR_VALID_CHECK(p_ctc_statsid);

    if (SYS_TMM_STATS_TYPE_VRF(lchip, p_ctc_statsid->type) || SYS_TMM_STATS_TYPE_SDC(lchip, p_ctc_statsid->type))
    {
        return CTC_E_NOT_SUPPORT;
    }
    else if(((CTC_STATS_STATSID_TYPE_ECMP == p_ctc_statsid->type || CTC_STATS_STATSID_TYPE_HECMP == p_ctc_statsid->type ) && p_ctc_statsid->dir == CTC_EGRESS)||
                             (CTC_STATS_STATSID_TYPE_NSH == p_ctc_statsid->type && p_ctc_statsid->dir == CTC_INGRESS))
    {
        return CTC_E_INVALID_PARAM;
    }
    CTC_ERROR_RETURN(_sys_usw_flow_stats_map_type(lchip, p_ctc_statsid->type, p_ctc_statsid->statsid.is_vc_label, &type, &dir));
    sal_memset(&sys_statsid, 0, sizeof(sys_statsid));
    sys_statsid.common.stats_id = p_ctc_statsid->stats_id;
    sys_statsid.color_aware = p_ctc_statsid->color_aware;
    sys_statsid.common.stats_id_type = type;
    sys_statsid.common.dir = (dir == CTC_BOTH_DIRECTION) ? p_ctc_statsid->dir : dir;
    SYS_STATS_SET_STABLE_EN(sys_statsid.common.stats_ptr, (CTC_STATS_STATSID_TYPE_ACL2 == p_ctc_statsid->type));
    if (SYS_STATS_TYPE_ACL == type)
    {
        if (CTC_BOTH_DIRECTION == dir && CTC_BOTH_DIRECTION == p_ctc_statsid->dir)
        {
            return CTC_E_INVALID_PARAM;
        }
        sys_statsid.acl_priority = p_ctc_statsid->statsid.acl_priority;
        if (CTC_INGRESS == sys_statsid.common.dir)
        {
            CTC_MAX_VALUE_CHECK(sys_statsid.acl_priority, MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM)-1);
        }
        else if (CTC_EGRESS == sys_statsid.common.dir)
        {
            CTC_MAX_VALUE_CHECK(sys_statsid.acl_priority, MCHIP_CAP(SYS_CAP_ACL_EGRESS_LKUP_NUM)-1);
        }
    }

    STATS_LOCK(lchip);
    if (usw_flow_stats_master[lchip]->stats_mode == CTC_STATS_MODE_USER && 
        usw_flow_stats_master[lchip]->flow_stats_id_hash->count >= usw_flow_stats_master[lchip]->max_stats_num)
    {
        STATS_UNLOCK(lchip);
        return CTC_E_NO_RESOURCE;
    }

    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_MASTER, 1);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_STATSID, 1);
    CTC_ERROR_RETURN_UNLOCK(_sys_usw_flow_stats_create_statsid(lchip, &sys_statsid));

    STATS_UNLOCK(lchip);

    p_ctc_statsid->stats_id = sys_statsid.common.stats_id;

    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_destroy_statsid(uint8 lchip, uint32 stats_id)
{
    SYS_STATS_DBG_FUNC();
    SYS_STATS_INIT_CHECK();
    CTC_MIN_VALUE_CHECK(stats_id, 1);

    STATS_LOCK(lchip);

    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_MASTER, 1);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_STATSID, 1);
    CTC_ERROR_RETURN_UNLOCK(_sys_usw_flow_stats_destroy_statsid(lchip, stats_id));

    STATS_UNLOCK(lchip);

    MCHIP_DMA(lchip)->dma_stats_func(lchip, SYS_DMA_FLOW_STATS_CHAN_ID);
    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_lookup_statsid(uint8 lchip, ctc_stats_statsid_type_t type, uint32 cache_ptr, uint32* p_statsid, uint8 dir)
{
    uint8 ram = 0;
    uint16 ptr_offset = 0;
    uint32 stats_ptr = 0;
    sys_stats_flow_stats_t* p_flow_stats = NULL;
    uint8 sys_type = SYS_STATS_TYPE_MAX;
    uint8 mapping_dir = CTC_BOTH_DIRECTION;
    uint8 pp_base = SYS_PP_BASE(lchip);
    SYS_STATS_DBG_FUNC();

    SYS_STATS_INIT_CHECK();
    CTC_PTR_VALID_CHECK(p_statsid);
    if (SYS_TMM_STATS_TYPE_VRF(lchip, type) || SYS_TMM_STATS_TYPE_SDC(lchip, type))
    {
        return CTC_E_NOT_SUPPORT;
    }
    if((DRV_IS_DUET2(lchip) && CTC_IS_BIT_SET(cache_ptr, 14)) || (DRV_IS_TSINGMA(lchip) && CTC_IS_BIT_SET(cache_ptr, 15)))
    {
        type = CTC_STATS_STATSID_TYPE_SDC;
    }

    CTC_ERROR_RETURN(_sys_usw_flow_stats_map_type(lchip,  type,  0, &sys_type, &mapping_dir));
    mapping_dir = ((mapping_dir == CTC_BOTH_DIRECTION) ? dir : mapping_dir);

    if (CTC_STATS_STATSID_TYPE_FID == type)
    {
        if (!SYS_STATS_TYPE_ENABLE(CTC_STATS_FID_STATS))
        {
            return CTC_E_NOT_SUPPORT;
        }
        stats_ptr = usw_flow_stats_master[lchip]->fid_base_ptr[mapping_dir] + cache_ptr;
        ram = SYS_STATS_DECODE_PTR_RAM(stats_ptr);
    }
    else if(CTC_STATS_STATSID_TYPE_ECMP == type)
    {
        stats_ptr = usw_flow_stats_master[SYS_PP_BASE(lchip)]->ecmp_base_ptr[0] + cache_ptr;
        ram = SYS_STATS_DECODE_PTR_RAM(stats_ptr);
    }
    else if(CTC_STATS_STATSID_TYPE_HECMP == type)
    {
        stats_ptr = (DRV_FROM_AT(lchip)? usw_flow_stats_master[SYS_PP_BASE(lchip)]->ecmp_base_ptr[1] : usw_flow_stats_master[SYS_PP_BASE(lchip)]->ecmp_base_ptr[0]) + cache_ptr;
        ram = SYS_STATS_DECODE_PTR_RAM(stats_ptr);
    }
    else
    {
        ram = _sys_usw_flow_stats_decode_hw_ptr(lchip, sys_type, mapping_dir, cache_ptr);
        stats_ptr = SYS_STATS_ENCODE_SYS_PTR(ram, DRV_IS_DUET2(lchip)? (cache_ptr)&0xFFF : (cache_ptr)&0x1FFF);
    }

    ptr_offset = SYS_STATS_DECODE_PTR_OFFSET(stats_ptr);
    SYS_MAP_LCHIP_WITH_LOCK(lchip, pp_base, sys_type, mapping_dir);
    p_flow_stats = ctc_vector_get(usw_flow_stats_master[lchip]->flow_stats_vec[ram], ptr_offset);
    if (p_flow_stats)
    {
        if(0 == p_flow_stats->stats_id)
        {
            SYS_STATS_DBG_ERROR(" statsptr not have stats id\n");
            STATS_UNLOCK(lchip);
            return CTC_E_INVALID_CONFIG;
        }
        *p_statsid = p_flow_stats->stats_id;
        STATS_UNLOCK(lchip);
        return CTC_E_NONE;
    }
    STATS_UNLOCK(lchip);
    return CTC_E_NOT_EXIST;
}

int32
sys_usw_flow_stats_get_stats(uint8 lchip, sys_stats_param_t* p_st, ctc_stats_basic_t* p_stats)
{
    uint8 i = 0;
    uint16 stats_num = 1;
    sys_stats_statsid_t sys_statsid_lkp;
    sys_stats_statsid_t* p_statsid_rse;
    ctc_stats_basic_t stats[4];
    uint32 tmp_st_ptr = 0;
    uint8 tmp_st_valid = 1;
    uint16 lport = 0;

    SYS_STATS_DBG_FUNC();
    SYS_STATS_INIT_CHECK();
    CTC_PTR_VALID_CHECK(p_st);
    CTC_PTR_VALID_CHECK(p_stats);

    if(p_st->type == SYS_STATS_TYPE_PORT)
    {
        if (!SYS_STATS_TYPE_ENABLE(CTC_STATS_PORT_STATS))
        {
            SYS_STATS_DBG_ERROR(" Port stats not support \n");
            return CTC_E_NOT_SUPPORT;
        }
        SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_st->ptr, lchip, lport);
    }

    MCHIP_DMA(lchip)->dma_stats_func(lchip, SYS_DMA_FLOW_STATS_CHAN_ID);
    STATS_LOCK(lchip);

    sal_memset(&stats, 0, sizeof(stats));
    if(p_st->id)
    {
        sal_memset(&sys_statsid_lkp, 0, sizeof(sys_statsid_lkp));
        sys_statsid_lkp.stats_id = p_st->id;
        p_statsid_rse = ctc_hash_lookup(usw_flow_stats_master[lchip]->flow_stats_id_hash, &sys_statsid_lkp);
        if (p_statsid_rse == NULL /*|| p_statsid_rse->stats_id_type != p_st->type*/)
        {
            SYS_STATS_DBG_ERROR(" Entry not exist \n");
            CTC_ERROR_RETURN_UNLOCK(CTC_E_NOT_EXIST);
        }
        p_st->num = stats_num = ((SYS_STATS_TYPE_ACL == p_statsid_rse->stats_id_type && STATS_SHARE_ACL_PTR(p_statsid_rse)->color_aware) ? 3:
                  (SYS_STATS_TYPE_NPM_IM == p_statsid_rse->stats_id_type ) ? 2 : 1);
        #if 0
        if ((DRV_IS_TSINGMA(lchip) && (p_statsid_rse->stats_id_type != SYS_STATS_TYPE_ACL && SYS_STATS_TYPE_QUEUE != p_statsid_rse->stats_id_type && SYS_STATS_TYPE_QUEUE_MC != p_statsid_rse->stats_id_type &&
             p_statsid_rse->stats_id_type != SYS_STATS_TYPE_NPM_IM)) && p_statsid_rse->stats_ptr == 0)   /* tbd*/
         {
            STATS_UNLOCK(lchip);
            return CTC_E_NONE;
        }
        #endif
        if(p_statsid_rse->stats_id_type == SYS_STATS_TYPE_NPM_IM && STATS_SHARE_NPM_PTR(p_statsid_rse)->egs_stats_ptr_valid)
        {
            p_st->num += 2;
            CTC_ERROR_RETURN_UNLOCK(_sys_usw_flow_stats_get_stats(lchip, STATS_SHARE_NPM_PTR(p_statsid_rse)->egs_stats_ptr, 2, stats+2));
        }
        tmp_st_ptr = p_statsid_rse->stats_ptr;
        tmp_st_valid = p_statsid_rse->stats_ptr_valid;
    }
    else
    {
        uint8 ram = 0;
        if(p_st->type <= SYS_STATS_TYPE_PORTTC_MC)
        {
            if (DRV_FROM_AT(lchip))
            {
                ram = SYS_STATS_RAM_AT_QUE_UC + p_st->type - SYS_STATS_TYPE_QUEUE;
                tmp_st_ptr = SYS_STATS_ENCODE_SYS_PTR(ram, p_st->ptr);
            }
            else if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
            {
                ram = SYS_STATS_RAM_QUE;
                tmp_st_ptr = SYS_STATS_ENCODE_SYS_PTR(ram, p_st->ptr);
            }
            else
            {
                tmp_st_ptr = usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_QUEUE].base_ptr + (p_st->ptr&0xFFFF);
            }
        }
        else if(p_st->type == SYS_STATS_TYPE_PORT)
        {
            tmp_st_ptr = usw_flow_stats_master[lchip]->port_base_ptr[p_st->dir&0x01] + lport;
        }
        else
        {
            ram = _sys_usw_flow_stats_decode_hw_ptr(lchip, p_st->type, p_st->dir, p_st->ptr);
            tmp_st_ptr = SYS_STATS_ENCODE_SYS_PTR(ram, DRV_IS_DUET2(lchip)?(p_st->ptr)&0xFFF:(p_st->ptr)&0x1FFF);
        }
        stats_num = p_st->num;
    }

    if(tmp_st_valid)
    {
        CTC_ERROR_DUMP(_sys_usw_flow_stats_get_stats(lchip, tmp_st_ptr, stats_num, stats));
    }

    STATS_UNLOCK(lchip);

    sal_memset(p_stats, 0, sizeof(ctc_stats_basic_t) * p_st->num);
    for (i=0; i<p_st->num; i++)
    {
        p_stats[i].byte_count = stats[i].byte_count;
        p_stats[i].packet_count = stats[i].packet_count;
    }

    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_clear_stats(uint8 lchip, sys_stats_param_t* p_st)
{
    uint8 stats_num = 1;
    sys_stats_statsid_t sys_statsid_lkp;
    sys_stats_statsid_t* p_statsid_rse;
    uint32 tmp_st_ptr = 0;
    uint16 lport = 0;
    uint8 npm_l_flag = 0;

    SYS_STATS_DBG_FUNC();
    SYS_STATS_INIT_CHECK();
    CTC_PTR_VALID_CHECK(p_st);

    if(p_st->type == SYS_STATS_TYPE_PORT)
    {
        if (!SYS_STATS_TYPE_ENABLE(CTC_STATS_PORT_STATS))
        {
            SYS_STATS_DBG_ERROR(" Port stats not support \n");
            return CTC_E_NOT_SUPPORT;
        }
        SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_st->ptr, lchip, lport);
    }

    MCHIP_DMA(lchip)->dma_stats_func(lchip, SYS_DMA_FLOW_STATS_CHAN_ID);
    STATS_LOCK(lchip);

    if(p_st->id)
    {
        sal_memset(&sys_statsid_lkp, 0, sizeof(sys_statsid_lkp));
        sys_statsid_lkp.stats_id = p_st->id;
        p_statsid_rse = ctc_hash_lookup(usw_flow_stats_master[lchip]->flow_stats_id_hash, &sys_statsid_lkp);
        if (p_statsid_rse == NULL || (p_st->type && p_statsid_rse->stats_id_type != p_st->type) )
        {
            SYS_STATS_DBG_ERROR(" Entry not exist \n");
            CTC_ERROR_RETURN_UNLOCK(CTC_E_NOT_EXIST);
        }
        stats_num = ((SYS_STATS_TYPE_ACL == p_statsid_rse->stats_id_type && STATS_SHARE_ACL_PTR(p_statsid_rse)->color_aware) ? 3:
                     (SYS_STATS_TYPE_NPM_IM == p_statsid_rse->stats_id_type && !(p_st->flag & SYS_STATS_FLAG_NPM_OP)) ? 2 : 1);

        npm_l_flag = (SYS_STATS_TYPE_NPM_IM == p_statsid_rse->stats_id_type && (p_st->flag & SYS_STATS_FLAG_NPM_LOSS));
        if(p_statsid_rse->stats_id_type == SYS_STATS_TYPE_NPM_IM && STATS_SHARE_NPM_PTR(p_statsid_rse)->egs_stats_ptr_valid)
        {
            CTC_ERROR_RETURN_UNLOCK(_sys_usw_flow_stats_clear_stats(lchip, stats_num, STATS_SHARE_NPM_PTR(p_statsid_rse)->egs_stats_ptr + npm_l_flag));
        }
        tmp_st_ptr = p_statsid_rse->stats_ptr + npm_l_flag;
    }
    else
    {
        uint8 ram = 0;
        if(p_st->type <= SYS_STATS_TYPE_PORTTC_MC)
        {
            if (DRV_FROM_AT(lchip))
            {
                ram = SYS_STATS_RAM_AT_QUE_UC + p_st->type - SYS_STATS_TYPE_QUEUE;
                tmp_st_ptr = SYS_STATS_ENCODE_SYS_PTR(ram, p_st->ptr);
            }
            else if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
            {
                ram = SYS_STATS_RAM_QUE;
                tmp_st_ptr = SYS_STATS_ENCODE_SYS_PTR(ram, p_st->ptr);
            }
            else
            {
                tmp_st_ptr = usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_QUEUE].base_ptr + (p_st->ptr&0xFFFF);
            }
        }
        else if(p_st->type == SYS_STATS_TYPE_PORT)
        {
            tmp_st_ptr = usw_flow_stats_master[lchip]->port_base_ptr[p_st->dir] + lport;
        }
        else
        {
            ram = _sys_usw_flow_stats_decode_hw_ptr(lchip, p_st->type, p_st->dir, p_st->ptr);
            tmp_st_ptr = SYS_STATS_ENCODE_SYS_PTR(ram, DRV_IS_DUET2(lchip)?(p_st->ptr)&0xFFF:(p_st->ptr)&0x1FFF);
        }
        stats_num = p_st->num ? p_st->num : 1;
    }

    CTC_ERROR_DUMP(_sys_usw_flow_stats_clear_stats(lchip, stats_num, tmp_st_ptr));
    STATS_UNLOCK(lchip);

    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_show_status(uint8 lchip)
{
    SYS_STATS_INIT_CHECK();
    MCHIP_F_STATS(lchip)->show_status(lchip);
    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_dump_db(uint8 lchip, sal_file_t p_f,ctc_global_dump_db_t* p_dump_param)
{
    int32 ret = CTC_E_NONE;
    uint32 index = 0;
    uint32 ram_index = 0;
    uint32 type = 0;
    uint8 ram_num = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);

    SYS_STATS_INIT_CHECK();
    STATS_LOCK(lchip);
    SYS_DUMP_DB_LOG(p_f, "%s\n", "# FLOW STATS");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "{");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "Master config:");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "-----------------------------------------------------------------------------------");
    SYS_DUMP_DB_LOG(p_f, "%-30s:0x%x\n", "Stats_bitmap", usw_flow_stats_master[lchip]->stats_bitmap);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "Stats_mode", usw_flow_stats_master[lchip]->stats_mode);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "Clear_read_on", usw_flow_stats_master[lchip]->clear_read_en);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%x\n", "Ecmp_base_ptr", usw_flow_stats_master[SYS_PP_BASE(lchip)]->ecmp_base_ptr[0]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%x\n", "HEcmp_base_ptr", usw_flow_stats_master[SYS_PP_BASE(lchip)]->ecmp_base_ptr[1]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%-9x%-9x\n", "Port_base_ptr", usw_flow_stats_master[lchip]->port_base_ptr[CTC_INGRESS], usw_flow_stats_master[lchip]->port_base_ptr[CTC_EGRESS]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%-9x%-9x\n", "Fid_base_ptr", usw_flow_stats_master[lchip]->fid_base_ptr[CTC_INGRESS], usw_flow_stats_master[lchip]->fid_base_ptr[CTC_EGRESS]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "Resource used num", usw_flow_stats_master[lchip]->alloc_count);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "Max stats number", usw_flow_stats_master[lchip]->max_stats_num);
    SYS_DUMP_DB_LOG(p_f, "%-6s%-4s%-12s%-9s%-12s\n","Type","Dir","Ram_bmp","Used_cnt","used_cnt_ram");
    for(index = 0; index < CTC_BOTH_DIRECTION; index++)
    {
        for (type=0; type<SYS_STATS_TYPE_MAX; type++)
        {
            SYS_DUMP_DB_LOG(p_f, "%-6u%-4u0x%-54"PRIx64"%-9u", type,index,usw_flow_stats_master[lchip]->stats_type[index][type].ram_bmp,usw_flow_stats_master[lchip]->stats_type[index][type].used_cnt);
            SYS_DUMP_DB_LOG(p_f,"[");
            for (ram_index=0; ram_index<ram_num-1; ram_index++)
            {
                SYS_DUMP_DB_LOG(p_f,"%u,", usw_flow_stats_master[lchip]->stats_type[index][type].used_cnt_ram[ram_index]);
            }
            SYS_DUMP_DB_LOG(p_f,"%u]\n", usw_flow_stats_master[lchip]->stats_type[index][type].used_cnt_ram[ram_index]);
        }
    }

    SYS_DUMP_DB_LOG(p_f, "%-30s:\n", "Stats_ram");
    SYS_DUMP_DB_LOG(p_f, " %-6s%-11s%-9s%-9s%-10s%-9s%-9s%-9s%-9s\n",
                       "Type", "Stats_bmp", "Cache_id", "Base_fid", "Total_cnt", "Used_cnt", "Base_ptr", "Base_idx", "Acl_pri");
    for(index = 0; index < ram_num; index++)
    {
        SYS_DUMP_DB_LOG(p_f, " %-6u0x%-9x%-9x%-9u%-9u%-10u%-9u%-9u%-9u%-9u\n",
                       index, usw_flow_stats_master[lchip]->p_stats_ram[index].stats_bmp[CTC_INGRESS],usw_flow_stats_master[lchip]->p_stats_ram[index].stats_bmp[CTC_EGRESS], usw_flow_stats_master[lchip]->p_stats_ram[index].cache_id, usw_flow_stats_master[lchip]->p_stats_ram[index].base_field_id, \
                       usw_flow_stats_master[lchip]->p_stats_ram[index].total_cnt, usw_flow_stats_master[lchip]->p_stats_ram[index].used_cnt, usw_flow_stats_master[lchip]->p_stats_ram[index].base_ptr, \
                       usw_flow_stats_master[lchip]->p_stats_ram[index].base_idx, usw_flow_stats_master[lchip]->p_stats_ram[index].acl_priority);
    }
    SYS_DUMP_DB_LOG(p_f, "%s\n", "-----------------------------------------------------------------------------------");
    SYS_DUMP_DB_LOG(p_f, "\n");
    sys_usw_opf_fprint_alloc_used_info(lchip, usw_flow_stats_master[lchip]->opf_type_flow_stats, p_f);
    if(usw_flow_stats_master[lchip]->opf_type_stats_id != 0)
    {
        sys_usw_opf_fprint_alloc_used_info(lchip, usw_flow_stats_master[lchip]->opf_type_stats_id, p_f);
    }
    SYS_DUMP_DB_LOG(p_f, "%s\n", "}");

    STATS_UNLOCK(lchip);

    return ret;
}

int32
sys_usw_stats_dump_db(uint8 lchip, sal_file_t p_f,ctc_global_dump_db_t* p_dump_param)
{
    sys_usw_mac_stats_dump_db(lchip, p_f, p_dump_param);
    sys_usw_flow_stats_dump_db(lchip, p_f, p_dump_param);

    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_get_stats_type_pp_en(uint8 lchip, ctc_stats_statsid_t* p_ctc_statsid, uint8* pp_en)
{
    uint8 type = 0;
    uint8 dir = 0;

    CTC_PTR_VALID_CHECK(pp_en);
    SYS_STATS_DBG_FUNC();

    CTC_ERROR_RETURN(_sys_usw_flow_stats_map_type(lchip, p_ctc_statsid->type, p_ctc_statsid->statsid.is_vc_label, &type, &dir));
    dir = (dir == CTC_BOTH_DIRECTION) ? p_ctc_statsid->dir : dir;

    STATS_LOCK(lchip);
    *pp_en = usw_flow_stats_master[lchip]->stats_type[dir][type].pp_en;
    STATS_UNLOCK(lchip);

    return CTC_E_NONE;
}

STATIC uint32
_sys_usw_flow_stats_get_stats_type_pp_en_by_stats_id(uint8 lchip, uint32 stats_id, uint8* pp_en)
{
    sys_stats_statsid_t statsid_lkp;
    sys_stats_statsid_t* p_statsid_rse = NULL;

    sal_memset(&statsid_lkp, 0, sizeof(statsid_lkp));
    statsid_lkp.stats_id = stats_id;
    p_statsid_rse = ctc_hash_lookup(usw_flow_stats_master[lchip]->flow_stats_id_hash, &statsid_lkp);
    if (p_statsid_rse == NULL)
    {
        SYS_STATS_DBG_ERROR(" Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    *pp_en = usw_flow_stats_master[lchip]->stats_type[p_statsid_rse->dir][p_statsid_rse->stats_id_type].pp_en;

    return CTC_E_NONE;
}


int32
sys_usw_flow_stats_get_stats_type_pp_en_by_stats_id(uint8 lchip, uint32 stats_id, uint8* pp_en)
{
    int32 ret = CTC_E_NONE;
    SYS_STATS_DBG_FUNC();
    CTC_PTR_VALID_CHECK(pp_en);

    STATS_LOCK(lchip);
    ret = _sys_usw_flow_stats_get_stats_type_pp_en_by_stats_id(lchip, stats_id, pp_en);
    STATS_UNLOCK(lchip);

    return ret;
}

int32
sys_usw_flow_stats_32k_ram_init(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 stats_offet = 0;
    uint32 loop = 0;
    sys_stats_ram_prop_t* p_ram = NULL;
    sys_stats_prop_t* p_prop = NULL;
    sys_stats_param_t sts_param;

    sal_memset(&sts_param, 0, sizeof(sts_param));
    cmd = DRV_IOR(IpeFlowHashCtl_t, IpeFlowHashCtl_igrIpfix32KMode_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
    if(!field_val)
    {
        return CTC_E_NONE;
    }
    SYS_STATS_INIT_CHECK();

    sts_param.num = 2;
    sts_param.type = SYS_STATS_TYPE_QUEUE;
    for(loop = 0; loop < MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT); loop ++)
    {
        cmd = DRV_IOR(DsErmQueueCfg_t, DsErmQueueCfg_statsPtr_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &stats_offet));
        sts_param.ptr = stats_offet;
        CTC_ERROR_RETURN(sys_usw_flow_stats_free_statsptr(lchip, &sts_param));
    }
    STATS_LOCK(lchip);
    sal_memset(usw_flow_stats_master[lchip]->p_stats_ram,0,SYS_STATS_RAM_MAX*sizeof(sys_stats_ram_prop_t));
    sal_memset(usw_flow_stats_master[lchip]->stats_type,0,SYS_STATS_TYPE_MAX*CTC_BOTH_DIRECTION*sizeof(sys_stats_prop_t));
    usw_flow_stats_master[lchip]->alloc_count = 0;

    /*init stats type*/
    p_prop = &(usw_flow_stats_master[lchip]->stats_type[CTC_INGRESS][SYS_STATS_TYPE_FLOW_HASH]);
    for(loop = 0; loop <= SYS_STATS_RAM_NUM_D2_TM; loop++)
    {
        if((SYS_STATS_RAM_EPE_GLOBAL0 == loop) || (SYS_STATS_RAM_EPE_GLOBAL1 == loop)
            || (SYS_STATS_RAM_EPE_GLOBAL2 == loop) || (SYS_STATS_RAM_EPE_GLOBAL3 == loop)
            || (SYS_STATS_RAM_IPE_GLOBAL0 == loop) || (SYS_STATS_RAM_IPE_GLOBAL1 == loop)
            || (SYS_STATS_RAM_IPE_GLOBAL2 == loop) || (SYS_STATS_RAM_IPE_GLOBAL3 == loop))
        {
            CTC_BIT64_SET(p_prop->ram_bmp, loop);
            CTC_BIT_SET(usw_flow_stats_master[lchip]->p_stats_ram[loop].stats_bmp[CTC_INGRESS], SYS_STATS_TYPE_FLOW_HASH);
        }
    }
    /*init stats ram*/
    sys_usw_opf_deinit(lchip, usw_flow_stats_master[lchip]->opf_type_flow_stats);
    /*SYS_STATS_RAM_IPE_GLOBAL0*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL0]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsIngressGlobal0_t)/4*4;/*4096/4*4 = 4096 */
    p_ram->cache_id = DsStatsIngressGlobal0_t;
    p_ram->base_field_id = StatsCacheBasePtr_ipeGlobalStats0BasePtr_f;

    /*SYS_STATS_RAM_IPE_GLOBAL1*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL1]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsIngressGlobal1_t)/4*4;
    p_ram->cache_id = DsStatsIngressGlobal1_t;
    p_ram->base_field_id = StatsCacheBasePtr_ipeGlobalStats1BasePtr_f;

    /*SYS_STATS_RAM_IPE_GLOBAL2*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL2]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsIngressGlobal2_t)/4*4;
    p_ram->cache_id = DsStatsIngressGlobal2_t;
    p_ram->base_field_id = StatsCacheBasePtr_ipeGlobalStats2BasePtr_f;

    /*SYS_STATS_RAM_IPE_GLOBAL3*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_IPE_GLOBAL3]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsIngressGlobal3_t)/4*4;
    p_ram->cache_id = DsStatsIngressGlobal3_t;
    p_ram->base_field_id = StatsCacheBasePtr_ipeGlobalStats3BasePtr_f;

    /*SYS_STATS_RAM_EPE_GLOBAL0*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL0]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsEgressGlobal0_t)/4*4;
    p_ram->cache_id = DsStatsEgressGlobal0_t;
    p_ram->base_field_id = StatsCacheBasePtr_epeGlobalStats0BasePtr_f;

    /*SYS_STATS_RAM_EPE_GLOBAL1*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL1]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsEgressGlobal1_t)/4*4;
    p_ram->cache_id = DsStatsEgressGlobal1_t;
    p_ram->base_field_id = StatsCacheBasePtr_epeGlobalStats1BasePtr_f;

    /*SYS_STATS_RAM_EPE_GLOBAL2*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL2]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsEgressGlobal2_t)/4*4;
    p_ram->cache_id = DsStatsEgressGlobal2_t;
    p_ram->base_field_id = StatsCacheBasePtr_epeGlobalStats2BasePtr_f;

    /*SYS_STATS_RAM_EPE_GLOBAL3*/
    p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[SYS_STATS_RAM_EPE_GLOBAL3]);
    p_ram->total_cnt = DRV_TABLE_MAX_INDEX(lchip, DsStatsEgressGlobal3_t)/4*4;
    p_ram->cache_id = DsStatsEgressGlobal3_t;
    p_ram->base_field_id = StatsCacheBasePtr_epeGlobalStats3BasePtr_f;

    //CTC_ERROR_RETURN_WITH_UNLOCK(_sys_usw_flow_stats_ram_alloc(lchip),usw_flow_stats_master[lchip]->p_stats_mutex);
    STATS_UNLOCK(lchip);
    return CTC_E_NONE;
}

#define __10_STATS_INIT__
int32
_sys_usw_flow_stats_wb_init(uint8 lchip)
{
    ctc_wb_appid_t  appid;

    sal_memset(&appid, 0, sizeof(appid));
    appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_MASTER) ;
    appid.entry_num = SYS_WB_FEATURE_MASTER_NUM;
    appid.entry_size  = sizeof(sys_wb_stats_master_t);
    appid.rt_en = 0;
    ctc_wb_add_appid( lchip, &appid);

    appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_STATS, SYS_WB_APPID_STATS_SUBID_STATSID) ;
    appid.entry_num = usw_flow_stats_master[lchip]->max_stats_num;
    appid.entry_size  = sizeof(sys_wb_stats_statsid_t);
    appid.rt_en = 0;
    ctc_wb_add_appid( lchip, &appid);

    return 0;
}

int32
_sys_usw_flow_stats_vec_init(uint8 lchip)
{
    uint8 ram = 0;
    uint8 stats_ram_num = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);
    uint16 total_cnt = 0;

    stats_ram_num =  DRV_FROM_AT(lchip) ? stats_ram_num - 6: stats_ram_num;
    for (ram=0; ram<stats_ram_num; ram++)
    {
        total_cnt = usw_flow_stats_master[lchip]->p_stats_ram[ram].total_cnt;
        usw_flow_stats_master[lchip]->flow_stats_vec[ram] = ctc_vector_init(total_cnt/SYS_STATS_PTR_VEC_SIZE, SYS_STATS_PTR_VEC_SIZE);
        if(usw_flow_stats_master[lchip]->flow_stats_vec[ram] == NULL)
        {
            return CTC_E_NO_RESOURCE;
        }
    }
    if(DRV_FROM_AT(lchip))
    {
        for(ram = SYS_STATS_RAM_AT_QUE_UC; ram < SYS_STATS_RAM_AT_NUM; ram++)
        {
            total_cnt = usw_flow_stats_master[lchip]->p_stats_ram[ram].total_cnt;
            usw_flow_stats_master[lchip]->flow_stats_vec[ram] = ctc_vector_init(total_cnt/4, 4);
            if(usw_flow_stats_master[lchip]->flow_stats_vec[ram] == NULL)
            {
                return CTC_E_NO_RESOURCE;
            }
        }
    }
    return CTC_E_NONE;
}

int32
sys_usw_flow_stats_init(uint8 lchip, ctc_stats_global_cfg_t* stats_global_cfg)
{
    int32 ret = 0;
    uint8 i = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint8 ram_num = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);
    uint8 block_num = DRV_FROM_TMM(lchip) ? MCHIP_CAP(SYS_CAP_STATS_RAM_NUM) : 8;
    uint16 loop = 0;
    uint32 table_id;
    uint16 max_ecmp_num = 0;
    uint8 hecmp_en;
    sys_stats_ram_prop_t* p_ram = NULL;
    sys_stats_param_t sts_param;

    LCHIP_CHECK(lchip);

    /*init global variable*/
    if (NULL != usw_flow_stats_master[lchip])
    {
        return CTC_E_NONE;
    }

    usw_flow_stats_master[lchip] = (sys_stats_master_t*)mem_malloc(MEM_STATS_MODULE, sizeof(sys_stats_master_t));
    if (NULL == usw_flow_stats_master[lchip])
    {
        SYS_STATS_DBG_ERROR(" No memory \n");
        CTC_ERROR_GOTO(CTC_E_NO_MEMORY, ret, error_roll);
    }
    sal_memset(usw_flow_stats_master[lchip], 0, sizeof(sys_stats_master_t));
    usw_flow_stats_master[lchip]->p_stats_ram = mem_malloc(MEM_STATS_MODULE, sizeof(sys_stats_ram_prop_t) * ram_num);
    if (NULL == usw_flow_stats_master[lchip]->p_stats_ram)
    {
        SYS_STATS_DBG_ERROR(" No memory \n");
        CTC_ERROR_GOTO(CTC_E_NO_MEMORY, ret, error_roll);
    }
    sal_memset(usw_flow_stats_master[lchip]->p_stats_ram, 0, sizeof(sys_stats_ram_prop_t) * ram_num);

    sal_mutex_create(&(usw_flow_stats_master[lchip]->p_stats_mutex));
    if (NULL == usw_flow_stats_master[lchip]->p_stats_mutex)
    {
        ret = CTC_E_NO_MEMORY;
        goto error_roll;
    }

    usw_flow_stats_master[lchip]->stats_mode = (stats_global_cfg->stats_mode) ? CTC_STATS_MODE_DEFINE : CTC_STATS_MODE_USER;
    usw_flow_stats_master[lchip]->stats_bitmap = stats_global_cfg->stats_bitmap;
    if (!DRV_FROM_AT(lchip))
    {
        CTC_UNSET_FLAG(usw_flow_stats_master[lchip]->stats_bitmap, CTC_STATS_FID_STATS);
    }

    //CTC_ERROR_RETURN(_sys_usw_flow_stats_statsptr_bmp_init(lchip));
    usw_flow_stats_master[lchip]->statsptr_bmp = mem_malloc(MEM_STATS_MODULE, sizeof(sys_stats_bmp_t) * ram_num);
    if (NULL == usw_flow_stats_master[lchip]->statsptr_bmp)
    {
        SYS_STATS_DBG_ERROR(" No memory \n");
        CTC_ERROR_GOTO(CTC_E_NO_MEMORY, ret, error_roll);
    }
    sal_memset(usw_flow_stats_master[lchip]->statsptr_bmp, 0, sizeof(sys_stats_bmp_t) * ram_num);

    CTC_ERROR_GOTO(sys_usw_nh_get_max_ecmp_group_num(lchip, &max_ecmp_num, &hecmp_en), ret , error_roll);
    usw_flow_stats_master[lchip]->max_ecmp_num = max_ecmp_num;
    usw_flow_stats_master[lchip]->hecmp_en = hecmp_en;

    /* sys stats resource init */
    CTC_ERROR_GOTO(MCHIP_F_STATS(lchip)->stats_type_init(lchip), ret, error_roll);
    CTC_ERROR_GOTO(MCHIP_F_STATS(lchip)->stats_ram_init(lchip), ret, error_roll);
    CTC_ERROR_GOTO(_sys_usw_flow_stats_vec_init(lchip), ret, error_roll);
    if(!(CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING))
    {
        CTC_ERROR_RETURN(_sys_usw_flow_stats_ram_alloc(lchip));
    }
    if(DRV_FROM_AT(lchip))
    {
        _sys_usw_flow_stats_determine_pp_ram(lchip);
    }
    usw_flow_stats_master[lchip]->max_stats_num = stats_global_cfg->max_stats_num ? stats_global_cfg->max_stats_num : (MCHIP_CAP(SYS_CAP_STATS_TOTAL_SIZE) / SYS_PP_NUM(lchip));

    /* global cfg init */
    CTC_ERROR_GOTO(_sys_usw_flow_stats_global_init(lchip), ret, error_roll);
    CTC_ERROR_GOTO(_sys_usw_flow_stats_statsid_init(lchip), ret, error_roll);

    /* reg callback init */
    if (!sys_usw_dma_get_flow_stats_sync_mode(lchip))
    {
        CTC_ERROR_GOTO(sys_usw_interrupt_register_isr(SYS_CHIP_CONVERT(lchip), SYS_INTR_FUNC_STATS_STATUS_ADDR, sys_usw_flow_stats_sync_fifo_stats), ret, error_roll);
        CTC_ERROR_GOTO(sys_usw_interrupt_register_isr(SYS_CHIP_CONVERT(lchip), SYS_INTR_FUNC_STATS_STATUS_ADDR_SLICE_1, sys_usw_flow_stats_sync_fifo_stats), ret, error_roll);
        CTC_ERROR_GOTO(sys_usw_interrupt_register_isr(SYS_CHIP_CONVERT(lchip), SYS_INTR_FUNC_STATS_STATUS_ADDR_SLICE_2, sys_usw_flow_stats_sync_fifo_stats), ret, error_roll);
        CTC_ERROR_GOTO(sys_usw_interrupt_register_isr(SYS_CHIP_CONVERT(lchip), SYS_INTR_FUNC_STATS_STATUS_ADDR_SLICE_3, sys_usw_flow_stats_sync_fifo_stats), ret, error_roll);
    }
    CTC_ERROR_GOTO(sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_FLOW_STATS,_sys_usw_flow_stats_sync_flow_stats), ret, error_roll);
    CTC_ERROR_GOTO(sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_SDC_STATS, _sys_usw_flow_stats_sync_sdc_stats), ret, error_roll);
    CTC_ERROR_GOTO(sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_FLOW_STATS_RAM_STATUS, sys_usw_flow_stats_get_ram_status),ret ,error_roll);
    CTC_ERROR_GOTO(sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_STATS,SYS_WB_APPID_STATS_SUBID_MAX, _sys_usw_flow_stats_wb_sync), ret, error_roll);
    CTC_ERROR_GOTO(sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_STATS, sys_usw_stats_dump_db), ret, error_roll);

    /* wormboot data restore */
    if (CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_RETURN(_sys_usw_flow_stats_wb_restore(lchip));
    }
    if (CTC_WB_ENABLE(lchip))
    {
        _sys_usw_flow_stats_wb_init(lchip);
    }

    /*init stats capability*/
    if (DRV_FROM_TMM(lchip))
    {
        for (i = 0; i < block_num; i++)
        {
            drv_usw_ftm_get_flow_stats_table_id(lchip, i, &table_id);
            MCHIP_CAP(SYS_CAP_SPEC_TOTAL_STATS_NUM) +=  DRV_TABLE_MAX_INDEX(lchip, table_id);
        }
    }
    else
    {
        MCHIP_CAP(SYS_CAP_SPEC_TOTAL_STATS_NUM) =  DRV_TABLE_MAX_INDEX(lchip, DsStats_t);
    }

    cmd = DRV_IOW(IpeFwdStatsCtl_t, IpeFwdStatsCtl_portStatsIncludeInternal_f);
    field_value = 0;
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value), ret, error_roll);

    cmd = DRV_IOW(EpeHeaderEditCtl_t, EpeHeaderEditCtl_portStatsIncludeInternal_f);
    field_value = 0;
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value), ret, error_roll);


    for (i = 0; i < MCHIP_CAP(SYS_CAP_DP_MAX_NUM); i++)
    {
        field_value = 0;
        cmd = DRV_IOW(NetRxCtl_t, NetRxCtl_cfgLengthWithoutBrgHdr_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, i), &field_value), ret, error_roll);

        cmd = DRV_IOW(NetRxCtl_t, NetRxCtl_cfgLoopOrLogLengthWithoutBrgHdr_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, i), &field_value), ret, error_roll);

    }

    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        cmd = DRV_IOW(NetRxCtl_t, NetRxCtl_cfgLengthWithoutBrgHdr_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 1, DRV_CMD_PP_EN(cmd), &field_value), ret, error_roll);
    }

    sal_memset(&sts_param, 0, sizeof(sts_param));
    sts_param.type = SYS_STATS_TYPE_QUEUE;
    /* init queue stats */
    if(DRV_IS_TSINGMA(lchip))
    {
        sts_param.num = 2;
        for(loop = 0; loop < MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT); loop ++)
        {
            CTC_ERROR_GOTO(sys_usw_flow_stats_alloc_statsptr(lchip, &sts_param),ret ,error_roll);
            cmd = DRV_IOW(DsErmQueueCfg_t, DsErmQueueCfg_statsPtr_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &sts_param.ptr), ret ,error_roll);
            cmd = DRV_IOW(DsErmQueueCfg_t, DsErmQueueCfg_statsMode_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &field_value), ret ,error_roll);
        }
    }
    else if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        /*alloc  12k basic qos statsprt*/
        sts_param.num = MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM);
        CTC_ERROR_GOTO(sys_usw_flow_stats_alloc_statsptr(lchip, &sts_param),ret ,error_roll);
    }
    else if(DRV_FROM_AT(lchip))
    {
        uint8 pp_base = SYS_PP_BASE(lchip);
        for(loop = SYS_STATS_RAM_AT_QUE_UC; loop < SYS_STATS_RAM_AT_PORTTC_MC ; loop++)
        {
            p_ram = &(usw_flow_stats_master[lchip]->p_stats_ram[loop]);
            if ( lchip == pp_base || p_ram->pp_en )
            {
                sts_param.type = loop-SYS_STATS_RAM_AT_QUE_UC + SYS_STATS_TYPE_QUEUE;
                sts_param.num = p_ram->total_cnt;
                CTC_ERROR_GOTO(sys_usw_flow_stats_alloc_statsptr(lchip, &sts_param), ret , error_roll);
            }
        }
    }
    usw_flow_stats_master[lchip]->init_entry_cnt = _sys_usw_flow_stats_vec_cnt(lchip);
    //ctc_hash_get_count(usw_flow_stats_master[lchip]->flow_stats_hash, &(usw_flow_stats_master[lchip]->init_entry_cnt));

    sys_usw_mchip_set_feature_en(lchip,CTC_FEATURE_STATS);
    return CTC_E_NONE;

error_roll:

    if (NULL != usw_flow_stats_master[lchip])
    {
        if(NULL != usw_flow_stats_master[lchip]->p_stats_ram)
        {
            mem_free(usw_flow_stats_master[lchip]->p_stats_ram);
        }
        if(NULL != usw_flow_stats_master[lchip]->statsptr_bmp)
        {
            mem_free(usw_flow_stats_master[lchip]->statsptr_bmp);
        }
        if (NULL != usw_flow_stats_master[lchip]->flow_stats_id_hash)
        {
            ctc_hash_free(usw_flow_stats_master[lchip]->flow_stats_id_hash);
        }

        if (usw_flow_stats_master[lchip]->stats_mode == CTC_STATS_MODE_DEFINE)
        {
            sys_usw_opf_deinit(lchip, usw_flow_stats_master[lchip]->opf_type_stats_id);
        }

        sys_usw_opf_deinit(lchip, usw_flow_stats_master[lchip]->opf_type_flow_stats);

        if (usw_flow_stats_master[lchip]->p_stats_mutex)
        {
            sal_mutex_destroy(usw_flow_stats_master[lchip]->p_stats_mutex);
        }

        mem_free(usw_flow_stats_master[lchip]);
        usw_flow_stats_master[lchip] = NULL;
    }

    return ret;
}

int32
sys_usw_flow_stats_deinit(uint8 lchip)
{
    uint8 ram = 0;
    uint8 max_ram = MCHIP_CAP(SYS_CAP_STATS_RAM_NUM);
    LCHIP_CHECK(lchip);

    if (NULL == usw_flow_stats_master[lchip])
    {
        return CTC_E_NONE;
    }
    sys_usw_interrupt_register_isr(SYS_CHIP_CONVERT(lchip), SYS_INTR_FUNC_STATS_STATUS_ADDR, NULL);
    sys_usw_interrupt_register_isr(SYS_CHIP_CONVERT(lchip), SYS_INTR_FUNC_STATS_STATUS_ADDR_SLICE_1, NULL);
    sys_usw_interrupt_register_isr(SYS_CHIP_CONVERT(lchip), SYS_INTR_FUNC_STATS_STATUS_ADDR_SLICE_2, NULL);
    sys_usw_interrupt_register_isr(SYS_CHIP_CONVERT(lchip), SYS_INTR_FUNC_STATS_STATUS_ADDR_SLICE_3, NULL);
    sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_FLOW_STATS, NULL);
    sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_SDC_STATS, NULL);
    sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_STATS,0, NULL);
    sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_STATS, NULL);
    if(NULL != usw_flow_stats_master[lchip]->p_stats_ram)
    {
        mem_free(usw_flow_stats_master[lchip]->p_stats_ram);
    }
    if(NULL != usw_flow_stats_master[lchip]->statsptr_bmp)
    {
        mem_free(usw_flow_stats_master[lchip]->statsptr_bmp);
    }

    sal_mutex_destroy(usw_flow_stats_master[lchip]->p_stats_mutex);

    if (NULL != usw_flow_stats_master[lchip]->flow_stats_id_hash)
    {
        /*free stats statsid*/
        ctc_hash_free2(usw_flow_stats_master[lchip]->flow_stats_id_hash, (hash_traversal_fn)_sys_usw_flow_stats_free_node, NULL);
    }

    for(ram = 0; ram < max_ram; ram++)
    {
        /*free stats statsid*/
        ctc_vector_traverse(usw_flow_stats_master[lchip]->flow_stats_vec[ram], (hash_traversal_fn)_sys_usw_flow_stats_free_node, NULL);
        ctc_vector_release(usw_flow_stats_master[lchip]->flow_stats_vec[ram]);
    }

    if (usw_flow_stats_master[lchip]->stats_mode == CTC_STATS_MODE_DEFINE)
    {
        sys_usw_opf_deinit(lchip, usw_flow_stats_master[lchip]->opf_type_stats_id);
    }

    sys_usw_opf_deinit(lchip, usw_flow_stats_master[lchip]->opf_type_flow_stats);
    mem_free(usw_flow_stats_master[lchip]);
    usw_flow_stats_master[lchip] = NULL;

    return CTC_E_NONE;
}

